leetcode 3无重复字符的最长子串(C#)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/moon_goes/article/details/102139504

题目

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

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

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

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

解题:

题目解释中给出了提示,我们要寻找的时最长子串,子串的含义是这个字符串每个字符在位置上必须是相邻的。

解法一:暴力解法
用一个string存储当前判断中的字符串,每加入一个新字符时,遍历该字符串中是否已存在该字符,若存在则直接把该字符串返回给List,如果不存在就添加该字符。最后遍历List,找到最长子串。但是该方法运行超时,只能抛弃。

解法二:滑动窗口
1.设置两个标志位start和end,初始值都为0,代表指向string第一个字符。
2.创建一个hash表,key存储字符,value存储该字符在字符串中的位置+1(+1是的目的是,如果检测的字符与该字符相同,那么新字符想要不重复,必须除去前面重复的字符,新字符串开始的位置则是该字符在字符串中的位置+1,即value值)。——这部分建议自己动手画图好理解一点。
简单来说,这个hash表存储的信息就是**(字符a,a出现重复时新字符串的起始位置)**。

两种例子:
【1】重复字符相邻:字符串“abba”,检测到第三个字符时出现重复,那么新的字符串应该从第三个字符开始才不会重复。
【2】重复字符不相邻:字符串“dvdf”,检测到第三个字符时出现重复,那么新字符串应该从第二个字符开始才不会重复。

3.end不断自增,start则是出现重复字符时才会改变;最长子串长度计算为(end-start+1)。

需要注意的点:
start值改变的时候,需要比较目前start的值和目标值,因为像“abba”字符串这种情况,判断进行到“ba”时,此时start指向b,end指向a,a在hash表中有存储,其value是1,如果直接把value值赋给start,显然新字符串不能从第一个a开始。所以比较**start =Math.Max((int)hs[s[end]],start);**这条语句防止以上情况出现。(之前没有比较导致我结果出错,逐语句执行才发现错误,f11还是很有必要的)

//C#代码
public class Solution {
    public int LengthOfLongestSubstring(string s) {
        Hashtable hs = new Hashtable();
            int n = s.Length;
            int ans = 0;
            int start = 0;
            for (int end = 0; end < n; end++)
            {
                if (hs.ContainsKey(s[end]))
                {
                     start =Math.Max((int)hs[s[end]],start);
                     hs[s[end]]=end+1;
                }
                else hs.Add(s[end], end + 1);
                ans = Math.Max(end - start + 1, ans);
            }
            return ans;
    }
}

思路和代码参考了这位大佬:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/hua-jie-suan-fa-3-wu-zhong-fu-zi-fu-de-zui-chang-z/

猜你喜欢

转载自blog.csdn.net/moon_goes/article/details/102139504