给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
题解
/* 最长无重复字符串的长度 */ int lengthOfLongestSubstring(char * s){//暴力法 int len=strlen(s);//获取字符串长度 if(!len)//如果len为0,就返回0 { return 0; } else if(len==1)//如果len=1,返回1 { return 1; } else { int start=0,end=1; int i; int max_len=1,cur_len=1;//最大长度,当前的长度 char temp_char; while (end<len) { temp_char=s[end]; for(i=start;i<end;i++) { if(s[i]==temp_char) { cur_len=end-start; if(cur_len>max_len) { max_len=cur_len; } start=i+1; break; } } end++; } if(max_len>(end-start)) { return max_len; } else { return (end-start); } } }
本题目使用解法偏向暴力法,时间复杂度偏向于O(n^2)。接下来总结一下思路。
首先,我们要求最长的无重复的最长子字符串。我们的目的是列举出所有的字符串,并从这些字符串中找到一个长度最长且没有重复字符的字符串。分开来说就是三点。
1.列举所有字符串
2.判断该字符串有没有重复字符
3.从这些没有重复字符的字符串中找到一个长度最长的字符串。
接下来,我们详细的来思考这个问题。
1.如果这个字符串长度为0,结果直接返回0,长度为1的话,直接返回1.
2.当该字符串长度>=2的时候,我们设置两个边界。start和end,其就像刀一样截取子字符串长度为[start,end)。
3.为了解决是否存在重复字符的问题,我们每次向当前子字符串尾根据条件插入一个新的字符s[end],从s[start]到s[end-1]依次检查是否存在和s[end]相等的元素,如果没有就把end添加到子字符串的末尾end++,否则说明如果加上末尾这个字符整个字符串就有重复字符了,应当及时止损。记录此时从start到(end-1)的长度,记为当前无重复子字符串的长度,如果其比当前最长无重复字符串长,就更新最长无重复子字符串。之后start应当跳转到重复字符位置的前一个位置即i+1,为什么这么做呢?而不是start++呢?
4.因为如果start++可能使得start在重复字符的前面,接下来end++会使得新的子字符串依然包含重复字符。
5.为什么最后要有比较(max_len)和(end-start)的判断呢?假如字符串都是没有重复的,那么就不会执行更新max_len的操作,这时候就要在最后判断一下是否max_len>(end-start)