“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;
}
}