977.有序数组的平方
数组其实是有序的, 只不过考虑到负数平方之后可能成为最大数。
那么数组平方的最大值就在数组的两端,不是最左边就是最右边。
此时可以考虑双指针法了,i指向起始位置,j指向终止位置,左右比较谁大再塞到数组中。
定义一个新数组result,考虑到先塞最大值,于是让k指向result数组终止位置。
vector<int> sortedSquares(vector<int>& nums) {
vector<int> result(nums.size());
int i = 0;
int j = nums.size()-1;
while(i <= j)
{
if(nums[i]*nums[i] < nums[j]*nums[j])
{
result[j-i] = nums[j]*nums[j];
j--;
}
else
{
result[j-i] = nums[i]*nums[i];
i++;
}
}
return result;
}
209.长度最小的子数组
滑动窗口,主要确定如下三点:
- 窗口内是什么? 满足判断条件的区间
- 如何移动窗口的起始位置? 在满足条件的前提下缩小区间范围
- 如何移动窗口的结束位置? 此区间不满足条件了,移动终点寻找下一个区间
本题中 窗口就是 条件满足其和 ≥ s 的长度最小的 连续 子数组。
窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了。
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
int minSubArrayLen(int target, vector<int>& nums) {
int i = 0;
int result = nums.size();
int sum = 0;
for(int j=0; j<nums.size(); j++)
{
sum += nums[j];
while(sum >= target)
{
int subL = j - i + 1;
result = min(subL, result);
sum -= nums[i++];
}
}
// if(sum < target && i == 0)
// {
// return 0;
// }
return (sum < target && i == 0) ? 0 : result;
}
使用 ?运算符简化代码
904. 水果成篮
本题中使用到了红黑树unordered_map,这个数据结构很常用
unordered_map<T1, T2> 通常T1代表元素,T2代表元素出现次数
int totalFruit(vector<int>& fruits) {
unordered_map<int, int> cnt;
int ans = 0;
for (int i = 0, j = 0; i < fruits.size(); ++i) {
int x = fruits[i];
++cnt[x];
while (cnt.size() > 2) {
int y = fruits[j++];
if (--cnt[y] == 0)
cnt.erase(y);
}
ans = max(ans, i - j + 1);
}
return ans;
}
76. 最小覆盖子串(难)
补充
string minWindow(string s, string t) {
//设置哈希表用来存放窗口值以及进行比较的值
unordered_map<char, int> need, win;
//将我们所需要的值加入到哈希表(需要进行比较的值)
for (auto &i : t) ++need[i];
int left = 0, right = 0, count = 0, len = INT_MAX, start = 0;
//开始对窗口进行处理
while (right < s.size()) {
//如果我们此时字符串中的元素在我们的需要窗口中的话
//我们就需要扩充窗口
if (need.find(s[right]) != need.end()) {
//此时进行扩充窗口
++win[s[right]];
//运用count来进行确保我们此时的窗口值完全覆盖了我们需要的子串
if (win[s[right]] == need[s[right]]) {
++count;
}
}
//如果此时的窗口值完全覆盖了我们需要的子串,就要进行缩小窗口的操作
while (count == need.size()) {
//这里是进行更新我们的最小子串
if (len > right - left + 1) {
start = left;
len = right - left + 1;
}
//这里开始对窗口进行处理
//如果此时的窗口左侧的值在我们的哈希表中的话
//就要进行判断是否要对count进行处理
if (need.find(s[left]) != need.end()) {
//如果此时的窗口左侧的值在哈希表中且数量和哈希表中的数量一致
//就对count计数位进行减一操作
if (need[s[left]] == win[s[left]]) {
--count;
}
//将窗口左侧的值进行减一,缩小窗口
--win[s[left]];
}
++left;
}
++right;
}
return len == INT_MAX ? "" : s.substr(start, len);
}