leetcode的Hot100系列--3. 无重复字符的最长子串--滑动窗口

可以先想下这两个问题:
1、怎样使用滑动窗口?
2、如何快速的解决字符查重问题?

滑动窗口

可以想象一下有两个指针,一个叫begin,一个叫now

这两个指针就指定了当前正在比较无重复的字符串,当再往后读取一个字符的时候,就需要比较该字符在begin到now之间是否有重复,如果有重复的话,则记录当前字符串长度,然后把begin往后移动,继续寻找后面的无重复字符子串。

例如,这里的字符串是:“fabcade”。
1、当开始比较字符串的时候,begin指向了第一个字符f,now也指向了第一个字符f,当前只有一个字符,也就不需要比较是否重复。
2、然后读取第二个字符,begin依然指向f,now指向了字符a,这个就需要比较一下a是否与之前的相同,没有相同的就继续读取。
3、当now指向第二个a的时候,begin指向f,此时发现前面已经有了一个a了,(这里可以先记录一下当前字符串长度)所以begin就需要往后移动到a后面的b的位置,则当前的字符串为:bca,之后继续读取d,等等等。

总而言之,滑动窗口记录了当前无重复的字符串,当遇到重复的时候,就把begin指针往后移动到不重复的位置(也就是前面那个重复字符的后面),然后继续遍历字符串到最后。

如何快速字符查重

因为这里都是字符,可以直接把该字符作为数组下标,当读取到一个字符的时候,直接把该字符下标对应的值置为1,表示当前已经存在一个字符(其实就是相当于把字符作为hash的key),例如:

char array[127] = {0};
char data = 'a';
if (0 == array[data])  // 说明之前没有读到过该字符
{
    array[data] = 1;  // 置位,表示已经读到过该字符
}
else
{
    // 说明此字符重复
}

我们可以先想一下思路:
先初始化begin和now,然后循环读取字符串,每读取一个字符串,就在数组里查找一下,如果数组里不为0,就说明有重复的字符,需要把当前的字符串长度记录下来,然后begin往后移动到不重复的字符上,然后把该数组全部位置为0,再把begin后面的字符对应的数组置位1,最后再继续比较。
这么写当然也是可以,但不停的把数组置1再清0再置1,会很浪费时间,可以有其他方法吗?
当然是有的,我们可以这么写:

置位的时候,不填1,而填写当前字符所在的位置。

这样有什么好处呢?因为前面的begin,已经记录了当前字符串比较的起始位置,当读取到一个字符串:
如果他出现的位置在begin之前,就说明,虽然以前已经有了该字符,但那个是之前的事情了,不在现在的这个字符串范围之内,所以它还是不算重复的;
如果他上次出现的位置在begin之后,就说明在当前比较的字符串中已经有一个和他相同的字符了。
这样的话,通过位置信息就能够知道该字符在当前比较位置是否重复,就不需要反复的对数字进行清零和置位了。
在leetcode上,提高了9倍!(使用置位和清零花费44ms,使用位置标记花费4ms)


int lengthOfLongestSubstring(char * s){

    int local[127] = {0}, data;  // local数组就是用来记录每个字符出现的位置
    int lenNow = 0, lenMax = 0;
    int len = strlen(s);
    int begin = 1;
    for (int i=0; i<len; i++)
    {
        data = s[i];
        if ((0 == local[data]) || (begin > local[data]))
        {
            lenNow ++;
        }
        else
        {
            if (lenNow > lenMax)    lenMax = lenNow;
            lenNow = i + 1 - local[data];
            begin = local[data] + 1;  // 更新begin的位置
        }
        local[data] = i + 1;
        // 这里记录的位置是下标加1,也就是从1开始记录,为什么不从0开始记录呢?
        // 如果从0开始,那么0就有两种意思:该字符从没出现过,该字符出现的位置是0。当0正好又是begin的时候,比如字符串:"abca"
    }
    if (lenNow > lenMax)    lenMax = lenNow;
    return lenMax;
}

原文地址:https://www.cnblogs.com/payapa/p/11197838.html

时间: 2024-10-27 18:09:05

leetcode的Hot100系列--3. 无重复字符的最长子串--滑动窗口的相关文章

无重复字符的最长子串——滑动窗口法?

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1. 示例 3: 输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke&qu

【leetcode】 算法题3 无重复字符的最长子串

问题 给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. 给定 "bbbbb" ,最长的子串就是 "b" ,长度是1. 给定 "pwwkew" ,最长子串是 "wke" ,长度是3.请注意答案必须是一个子串,"pwke" 是 子序列  而不是子串 代码实现 class S

leetcode第三题:无重复字符的最长子串

public static int lengthOfLongestSubstring(String s) { int len = s.length(); int res = 0; int start = 0; int end = 0; HashSet set = new HashSet(); while (start < s.length() && end < s.length()) { if (set.contains(s.charAt(end))) { set.remove

leetcode力扣刷题系列python——3、无重复字符的最长子串

题目: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1. 解法: 采用哈希表法:设定左右双指针l和r,遍历字符串:哈希表存储某字符s[i]最新在字符串中出现的位置index + 1,key, value

Leetcode(3)无重复字符的最长子串

Leetcode(3)无重复字符的最长子串 [题目表述]: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 第一种方法:暴力 执行用时:996 ms: 内存消耗:12.9MB 效果:太差 class Solution(object): def lengthOfLongestSubstring(self, s): """ :type s: str :rtype: int """ Maxsize=0 res='' if len(s)

【Leetcode】【Longest Substring Without Repeating Characters】【无重复字符的最长子串】【C++】

题目:给定一字符串,求其无重复字符的最长子串长度. 思路:for循环一次,时间复杂度为O(N).字符的ascii值为32~126.start表示当前无重复字符子串的初始位置,初始值为0:可定义一个位置数组pos[128]表示for循环索引到当前位置时相应的字符对应的位置.若当前字符s[i](其ascii值为cur_pos),若pos[cur_pos]>=start,说明在start之后已有该字符s[i],则以start开始的子串第一次遇到重复字符,打住.判断当前长度是否大于max_len,若大于

[LeetCode]无重复字符的最长子串

给定一个字符串,找出不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 无重复字符的最长子串是 "abc",其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 无重复字符的最长子串是 "b",其长度为 1. 示例 3: 输入: "pwwkew" 输出: 3 解释: 无重复字符的最长子串是 "wke",其长度为 3.   请注

LeetCode 无重复字符的最长子串(探索字节跳动)

题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1. 示例 3: 输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "w

LeetCode 第3题 无重复字符的最长子串

/*3. 无重复字符的最长子串给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb"输出: 3解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb"输出: 1解释: 因为无重复字符的最长子串是 "b",所以其长度为 1. 示例 3: 输入: "pwwkew"输出: 3解释: 因为无重复字符的最长子串是 &qu