双指针总结
1.双指针
双指针解决数组,字符串,二分搜索,链表翻转、判断是否有环、寻找链表向后数第i个元素、链表中间的元素。
1.1有序数组两数之和
left = 0,right = arr.len -1
若arr[left]+arr[right] > sum,right--;否则left++;
1.2最小子串(双指针进阶-->滑动窗口)
给定字符串s,字符串t,求包含字符串t的所有字母的最小s连续子串。
思路:双指针滑动窗口一般用来解决字符串或者数组的子串或者子数组的最优问题。
首先另left、right指针等于0,right一直向右走,知道满足所给的条件。
然后,left向右走,每次向后走前,记录这次满足前的最优值,直到不满足退出。
left = right = 0
伪代码
while(right < str.len){
while(left到right之间的子串不满足条件){//即系left到right的子串满足条件就退出while
添加right指向的字符
right++;
}
while(left->right之间的字符串满足条件){
记录最优
left++;
}
}
leetcode 76
link:https://leetcode-cn.com/problems/minimum-window-substring/
#include <iostream>
#include <unordered_map>
using namespace std;
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char, int> needs,window;//用于判断s的子串是否包含t的全部字母
for (int i = 0; i < t.size(); i++)
{
needs[t[i]]++;
}
int left, right,valid=0;//满足条件的字母个数,若等于t的size,标识满足条件
int start, len = 1999999;
left = right = 0;
while (right < s.size())
{
char temp = s[right];
right++;//窗口先增大
if (needs.count(temp)) {
window[temp]++;
if (window[temp] == needs[temp]) {
valid++;
}
}
while (valid == needs.size())
{
if (right - left < len) {
len = right - left;
start = left;
}
char d = s[left];
left++;
if (needs.count(d)) {
if (window[d] == needs[d]) {
valid--;
}
window[d]--;
}
}
}
return len == 1999999 ? "" : s.substr(start, len);
}
};