2020-07-21LeetCodeNo.3、、滑动窗口算法学习

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

示例 1:

输入: "abcabcbb"

输出: 3

解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: "bbbbb"

输出: 1

解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: "pwwkew"

输出: 3

解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。

     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

我的思路是使用两重for循环达到暴力破解的目的,时间复杂度为O(nlogn)但是由于一直显示我缓冲区溢出但是在xcode以及vs里跑并没有出现缓冲区溢出的情况,所以准备学习一下别人的算法。

看到大概有两种方法,一种是使用hashmap,用一个数组存储各字母出现的次数(哈希表)。当不存在重复字母时滑动窗口不断向右延伸,直到出现重复字母或到达字符串结尾。检测到重复字母后,从左向右收缩滑动窗口,每次收缩都对哈希表进行更新。直到不存在重复字母时,滑动窗口才停止收缩,继续向右延伸。

这样的时间复杂度为O(n),但是由于我对哈希表的理解不够,所以选择去了解另一个算法:滑动窗口

滑动窗口的思路,用start存储子串的起始字符位置,index[128]对应了128个字符,即每个字符对应一个数值,起始都是默认为0,遍历后index[]存放的就是字符的位置+1(下一个起始字符的位置),当index[s[]>start的时候就代表出现了重复字符,然后计算该子串的长度,max存放的是最大长度,每次进行比较,遍历一遍后还需要进行一次子串长度计算并与max比较,因为最后一个子串是跳出循环外的了。

int lengthOfLongestSubstring(char * s){

    int index[128] = {0};

    int start=0,max=0,count=0;

    int i;

    for( i=0;s[i]!='\0';i++)

    {

        if(index[s[i]]>start)

        {

            count = i - start;

            start = index[s[i]];

            if(count>max)

            {

                max = count;

            }           

        }

        index[s[i]] = i+1;

    }

    count = i - start;

    if(count>max)

    {

        max = count;

    }

    return max;

}

第二种滑动窗口是:

int lengthOfLongestSubstring(char * s){

    int maxValue = 0; // the max length of substring, to return

    int tempMaxValue = 0; // temp length

    /* use sliding window */

    int slidingWindowHead = 0;

    int slidingWindowRear = 0;

    int slidingWindowQueue[128] = {0}; // ASCII of X86

    int length = strlen(s);

    if(length == 0)

    {

        return 0; // null string

    }

    while(slidingWindowHead <= (length - 1))

    {

        if(slidingWindowQueue[ s[slidingWindowHead] ] != 0) // find the same char

        {

            if(slidingWindowQueue[ s[slidingWindowHead] ] > slidingWindowRear) // ignore outer substring

            {

                slidingWindowRear = slidingWindowQueue[ s[slidingWindowHead] ]; // refresh rear of sliding window

            }

        }

        tempMaxValue = slidingWindowHead - slidingWindowRear + 1; // equal to sliding window length

        if(tempMaxValue > maxValue) // refresh max length

        {

            maxValue = tempMaxValue;

        }

        slidingWindowQueue[ s[slidingWindowHead] ] = slidingWindowHead + 1; // store the [string char <-> position] in queue

        slidingWindowHead++;

    }

    return maxValue;

}


附上知乎里搜到的关于滑动窗口的相关信息:

https://www.zhihu.com/topic/20746237/intro

2020年07月21日23:24:03

你可能感兴趣的:(2020-07-21LeetCodeNo.3、、滑动窗口算法学习)