🔥 LeetCode 热题 HOT 100: 75 && 76

204 阅读2分钟

“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”

75. 颜色分类

一、题目描述:

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库的sort函数的情况下解决这个问题。

 

示例 1:

输入:nums = [2,0,2,1,1,0]

输出:[0,0,1,1,2,2]

二、思路分析:

  • 类似快排的思路, 双指针 left, right,分别指向下一个红色, 蓝色的存放地址(0, nums.length - 1)

遍历过程中, index 位置的数字表示红色时, swap(left, index), left 指针向后移动一位, index++

index 位置的数字表示白色时, 不用交换 , index++

index 位置的数字表示蓝色时,swap(right, index) ,right指针向前移动一位, index 不动进入下次循环继续比较

三、AC 代码:

class Solution {
    public void sortColors(int[] nums) {
        int left = 0, right = nums.length - 1;

        int index = 0;

        while(index <= right){
            if(nums[index] == 0){
                // red
                swap(nums, left++, index++);
            }else if(nums[index] == 1){
                index++;
            }else{
                // blue
                swap(nums, right--, index);
            }
        }
    }

    void swap(int[] nums, int left, int right){
        int t = nums[left];
        nums[left] = nums[right];
        nums[right] = t;
    }
}

76. 最小覆盖子串

一、题目描述: 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

注意:

对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。 如果 s 中存在这样的子串,我们保证它是唯一的答案。  

示例 1:

输入:s = "ADOBECODEBANC", t = "ABC"

输出:"BANC"

二、思路分析:

  • 滑动窗口

need 数组 : t 中字符出现的频率

map 数组 : 当前窗口中字符出现的频率

count: 当前窗口字符串中满足t 字符的数量

滑动窗口滑动过程中,当 count等于t字符串的长度时,说明当前窗口可以满足要求,因为求的是最小窗口, 所以尝试对left 指针右移,收缩窗口, 收缩的过程中注意 map 中字符数量的变化

三、AC 代码:

class Solution {
    public String minWindow(String s, String t) {
        int len = t.length();
        int[] need = new int[128];
        int count = 0;

        for (int i = 0; i < t.length(); i++) {
            need[t.charAt(i) - 'A']++;
        }

        int left = 0, right = 0;
        int min = Integer.MAX_VALUE;
        String ans = "";
        int[] map = new int[128];

        while (right < s.length()) {

            char cur = s.charAt(right);
            int index = cur - 'A';
            map[index]++;
            if (map[index] <= need[index]) {
                count++;
            }

            if (count == len) {
                // 收缩窗口
                int l;
                while (left < right && ((l = s.charAt(left) - 'A') >= 0) &&
                        map[l] > need[l]) {
                    map[l]--;
                    left++;
                }

                if (right - left + 1 < min) {
                    min = right - left + 1;
                    ans = s.substring(left, right + 1);
                }
                map[s.charAt(left) - 'A']--;
                left++;
                count--;
            }
            right++;
        }

        return ans;

    }
}