前言

本文隶属于专栏《LeetCode 刷题汇总》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

本专栏目录结构请见LeetCode 刷题汇总

正文

幕布

在这里插入图片描述

幕布链接

76. 最小覆盖子串

题解

简简单单,非常容易理解的滑动窗口思想

滑动窗口

class Solution {
    public String minWindow(String s, String t) {
        if (s == null || s.length() == 0 || t == null || t.length() == 0){
            return "";
        }
        int[] need = new int[128];
        //记录需要的字符的个数
        for (int i = 0; i < t.length(); i++) {
            need[t.charAt(i)]++;
        }
        //l是当前左边界,r是当前右边界,size记录窗口大小,count是需求的字符个数,start是最小覆盖串开始的index
        int l = 0, r = 0, size = Integer.MAX_VALUE, count = t.length(), start = 0;
        //遍历所有字符
        while (r < s.length()) {
            char c = s.charAt(r);
            if (need[c] > 0) {//需要字符c
                count--;
            }
            need[c]--;//把右边的字符加入窗口
            if (count == 0) {//窗口中已经包含所有字符
                while (l < r && need[s.charAt(l)] < 0) {
                    need[s.charAt(l)]++;//释放右边移动出窗口的字符
                    l++;//指针右移
                }
                if (r - l + 1 < size) {//不能右移时候调整最小窗口大小,更新最小窗口开始的start
                    size = r - l + 1;
                    start = l;//记录下最小值时候的开始位置,最后返回覆盖串时候会用到
                }
                //l向右移动后窗口肯定不能满足了 重新开始循环
                need[s.charAt(l)]++;
                l++;
                count++;
            }
            r++;
        }
        return size == Integer.MAX_VALUE ? "" : s.substring(start, start + size);
    }
}

77. 组合

题解

官方题解

标准回溯

class Solution {
    private List<List<Integer>> results = new ArrayList<>();

    public List<List<Integer>> combine(int n, int k) {
        pick(new ArrayList<>(k), n, k, 1);
        return results;
    }

    private void pick(List<Integer> list, int n, int k, int cur){
        if(k <= 0){
            results.add(new ArrayList<>(list));
            return;
        }
        for(int i = cur; i <= n - k + 1; i++){
            list.add(i);
            pick(list, n, k-1, i + 1);
            list.remove(list.size() - 1);
        }
    }
}

78. 子集

题解

官方题解

标准回溯

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> list = new ArrayList<>();
        Arrays.sort(nums);
        backtrack(list, new ArrayList<>(), nums, 0);
        return list;
    }

    private void backtrack(List<List<Integer>> list , List<Integer> tempList, int [] nums, int start){
        list.add(new ArrayList<>(tempList));
        for(int i = start; i < nums.length; i++){
            tempList.add(nums[i]);
            backtrack(list, tempList, nums, i + 1);
            tempList.remove(tempList.size() - 1);
        }
    }
}

79. 单词搜索

题解

官方题解

同小岛沉没问题

class Solution {
    public boolean exist(char[][] board, String word) {
		for (int x = 0; x < board.length; x++) {
			for (int y = 0; y < board[0].length; y++) {
				if (board[x][y] == word.charAt(0) && helper(board, word, 0, x, y)) {
					return true;
				}
			}
		}
		return false;
	}

	private boolean helper(char[][] board, String word, int index, int x, int y) {
		if (x < 0 || x >= board.length || y < 0 || y >= board[0].length || board[x][y] != word.charAt(index)) {
			return false;
		}
		if (index == word.length() - 1) {
			return true;
		}
		board[x][y] = '*';
		boolean res = helper(board, word, index + 1, x + 1, y) ||
			helper(board, word, index + 1, x - 1, y) ||
			helper(board, word, index + 1, x, y + 1) ||
			helper(board, word, index + 1, x, y - 1);
		board[x][y] = word.charAt(index);
		return res;
	}
}

80. 删除有序数组中的重复项 II

题解

3-6 easy lines, C++, Java, Python, Ruby

双指针,一个用来遍历,一个用来占位

class Solution {
    public int removeDuplicates(int[] nums) {
        int i = 0;
        for (int n : nums)
            if (i < 2 || n > nums[i-2])
                nums[i++] = n;
        return i;
    }
}
上一篇 下一篇