每日刷题191122

  博主渣渣一枚,刷刷leetcode给自己瞅瞅,大神们由更好方法还望不吝赐教。题目及解法来自于力扣(LeetCode),传送门

算法:

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

示例 1:

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

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

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

public class Solution {
        public int LengthOfLongestSubstring(string s)
        {
            var includeList = new List<char>();

            int maxCount = 0;
            int count = 0;

            var strArray = s.ToArray();

            for (int i = 0; i < strArray.Length; i++)
            {
                if (!includeList.Contains(strArray[i]))
                {
                    count++;
                    includeList.Add(strArray[i]);

                    if (count > maxCount)
                    {
                        maxCount = count;
                    }
                }
                else
                {
                    var duplicateIndex = includeList.IndexOf(strArray[i]);
                    count = includeList.Count - duplicateIndex;

                    var tempIncludeList = includeList.Skip(duplicateIndex + 1).ToList();
                    includeList = tempIncludeList;
                    includeList.Add(strArray[i]);
                }
            }

            return maxCount;
        }
}

  这道题思路是这样的,用一个List储存当前不重复的整个字符串。重点在于遇到了第一个重复的字符串的时候。这时从这个位置向前一位开始,如果有比之前的字符串长度最大值长的就更新,否则就维持原状。这道题的边界值很有意思。可以看看这几个测试的用例:abcabc, bbbb, dvdf, pwwekw, anviaj等等。分别对应几种不同的情况,如重复的字符在之前的最大字符串中的不同位置,如pwwekw,w在之前最长字符串pw的末尾,anviaj在之前最大字符串的首位。

  因此,当我们找到重复的字符时,首先从当前位置向前找到重复的字符,这之间的长度就是我们下次比较最长长度的基础。因此此时的count的计算实际上是 includeList.Count - (duplicateIndex + 1)  + 1 。即两个重复字符直接的字符个数+当前这个字符。

  但上面这个方法的效率和时间复杂度都不够花,还有优化的空间。

  官方解法的传送门:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/wu-zhong-fu-zi-fu-de-zui-chang-zi-chuan-by-leetcod/

  第二种方法,滑动窗口很有意思,效率也足够好!

猜你喜欢

转载自www.cnblogs.com/dogtwo0214/p/11913244.html