题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其
长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b"
,所以其长度为 1。
示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke"
,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。
菜鸟解题版
public class Solution {
public int LengthOfLongestSubstring(string s) {
if (s.Length<=1) return s.Length;
int maxLength = 0;
int tempLength = 0;
int lastLength = 0;
Dictionary<int, char> myDictionary = new Dictionary<int, char>();
char tempChar;
int length = s.Length;
List<int> myList = new List<int>();
for (int i = 0; i < length; i++)
{
lastLength = length - i - 1;
if (lastLength + tempLength < maxLength)
{
return maxLength;
}
tempChar=s[i];
if (myDictionary.ContainsValue(tempChar))
{
if (tempLength > maxLength) maxLength = tempLength;
foreach (var item in myDictionary)
{
myList.Add(item.Key);
if (item.Value == s[i]) break;
}
for (int j = 0; j < myList.Count; j++)
{
myDictionary.Remove(myList[j]);
}
tempLength = tempLength-myList.Count;
myList.Clear();
}
tempLength++;
myDictionary.Add(i, tempChar);
//根据Key正向排序
//Dictionary排序是无序的,例如原版 0 1 2 3
//删除0 1 后,在添加4 5 6
//新的顺序为4 5 2 3 6
//此处按Key进行了正向排序
myDictionary= myDictionary.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value);
}
if (tempLength>maxLength) maxLength =tempLength;
return maxLength;
}
}
高手某一版
public class Solution {
public int LengthOfLongestSubstring(string s) {
//字符串转化为char[]数组
var array = s.ToCharArray();
int n = array.Length, ans = 0;
Dictionary<char, int> map = new Dictionary<char, int>();
for (int j = 0, i = 0; j < n; j++)
{
if (map.ContainsKey(array[j]))
{
//map[array[j]]
//i(赋值号两边)
i = Math.Max(map[array[j]], i);
}
ans = Math.Max(ans, j - i + 1);
map[array[j]] = j + 1;
}
return ans;
}
}
思路分析
以“abcdcd“为例
第一个重复字符 c
此时:map[array[j]] 为字典中c对应的值:3
赋值号右边的i 为上次出现重复的字符在字典中对应的值: 由于是第一次重复,此时为0
赋值号左边的i 为本次出现的字符c在字典中的对应的值:3
继续:ans记录最大子串 此时为4
j-i+1:表示如图区间 为2 判断是否超过了ans的值,若超过了更新ans
第二个重复字符 d
此时:map[array[j]] 为字典中d对应的值:4
赋值号右边的i 为上次出现重复的 字符c 在字典中对应的值: 3
赋值号左边的i 为本次出现的字符d在字典中的对应的值:4
继续:ans记录最大子串4
j-i+1:表示下一个区间3 判断是否超过了ans的值,若超过了更新ans
最终结果4
i = Math.Max(map[array[j]], i);的意义
上面d重复在了c的右边 i进行了更新;
当以“abcdca“为例时
这里a重复在c的左边 i 没有更新 ;
第二个重复字符 a
此时:map[array[j]] 为字典中a对应的值:1
赋值号右边的i 为上次出现重复的 字符c 在字典中对应的值: 3
赋值号左边的i 为上次出现重复的字符c在字典中的值:3 注意不是此次重复字符a 的1 正是此处判断最值的意义
继续:ans记录最大子串4
j-i+1:表示下一个区间4 判断是否超过了ans的值,若超过了更新ans
4没有超过4,结果无变化,若没有这个最值判断 以“abba”为例
第二个重复字符 a 赋值号右边的i 为1 j-i+1 =3-1+1=3 更新最值ans为3,错误