算法/滑动窗口

滑动窗口分为不固定窗口大小和固定窗口大小两种:(当要寻找符合某个要求的子串时常用

1)不固定窗口大小:窗口大小会变化,当前窗口不满足要求时,整体向后移。

2)   固定窗口大小:窗口大小为一个常数,当前窗口不满足要求时,整体向后移。

滑动窗口与双指针不同的地方就在于,双指针的变化方向是双向的,可以左指针向右,也可以右指针向左,而滑动窗口是整个窗口向右移,左右指针同步。

1.3. 无重复字符的最长子串

题目描述:

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例:

示例 1:
输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

解答描述:

要找到不含有重复字符的最长子串的长度,采用滑动窗口的思想。

枚举每个字符作为字符串的起点,找到以该字符作为起点的没有重复的最长字符串,当有重复时,立即停止,然后滑动窗口的左指针向右移,继续枚举下一个字符串。

因为滑动窗口内的字符一定是没有重复的,所以只需要判断右窗口之外的字符即可。

(注意,在C++中由于STL有容器,可以采用unordered_set来进行查重,当set.count==0的时候表示该元素没有重复,set.count==1的时候,表示容器内已经有该元素,会造成重复)

代码:

C++滑动窗口:

class Solution {
public:
    int max(int a,int b)
    {
        return a>b?a:b;
    }
    int lengthOfLongestSubstring(string s) {
        int l=0;//用来标志枚举字符串的起始位置
        int r=0;//用来找到当前枚举字符串的终止位置
        unordered_set ss;//用来去重
        int n=s.size();
        int max_str_len=0;
        int temp_len=0;//用来记录当前枚举字符串的最长子串长度
        while(l

C kmp算法:

//kmp算法
int max(int a,int b)
{
    return a>b?a:b;
}
int lengthOfLongestSubstring(char * s){
    int size=strlen(s);
    int max_len=0;
    int *next=malloc(sizeof(int)*256);
    //int next[256]={0};//用来记录每一轮各数出现的次数
    if(size<2)//当为空字符串时,直接返回0,当字符串只有一个字符时,返回1
    {
        return size;
    }
    memset(next,0,sizeof(next));        
    int j=0;
    for(int i=0;i

2.567. 字符串的排列

题目描述:

给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。

换句话说,s1 的排列之一是 s2 的 子串 。

示例:

示例 1:
输入:s1 = "ab" s2 = "eidbaooo"
输出:true
解释:s2 包含 s1 的排列之一 ("ba").

示例 2:
输入:s1= "ab" s2 = "eidboaoo"
输出:false

解答描述:

这道题的关键在于理解s2包含s1的排列,这意味着s2只要有一个子串和s1的元素种类和数量都相同即可。所以考虑用一个固定大小为s1.size()的滑动窗口来解决。

先用数组cnt1,cnt2分别记录s1的各个元素出现次数和s2当前窗口内的元素出现次数,如果cnt1和cnt2完全相同,说明匹配,返回true,否则的话,将滑动窗口整体向后移一步,更新cnt2,继续判断。

代码:

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        int n1=s1.size();
        int n2=s2.size();
        if(n1>n2)
        {
            return false;
        }
        vector cnt1(26);//用来统计固定大小为n1的滑动窗口内s1各字符出现次数
        vector cnt2(26);//用来统计固定大小为n1的滑动窗口内s2各字符出现次数
        for(int i=0;i

你可能感兴趣的:(LeetCode,算法,C语言,滑动窗口)