LeetCode03:无重复字符的最长字串
题目描述(难度中等)
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释:
因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
通过次数350,637提交次数1,064,854
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的解题
虽然很菜,但还是想和大家一起交流。我也想知道我这个还能怎么优化。
我们先分析字符串出现的情况:
重复的字符串是相邻的情况,重复字符串不相邻的情况,分别对应计算start与end更新的情况不同,
利用长数组map记录数组s的元素转化为整数,将这个整数作为map数组索引,值设为s对应元素索引+1,即对应元素个数
所以,读取s的元素,看map里面对应索引值是否为0,即可判断元素是否是重复元素。
首先我们先定义变量分别表示字符串的长度length,用来计算当前字串长度的索引start,end,记录最大长度字串maxlength。
int lengthOfLongestSubstring(char * s) {
int length = strlen(s);
int start=0,end=0,maxlength=0;
int map[256] = {0};
if(length==0)
return 0;
else {
while(end<length) {
if(map[(int)*(s+end)]==0) { //判断是否是重复元素
map[(int)*(s+end)] = end+1;//不是就将值设为s对应元素索引加1.
maxlength = maxlength>(end-start+1)?maxlength:(end-start+1);
}
else {
if(s[end-1]==s[end]) { //是重复元素,判断是否是相邻重复
start =end; //相邻,就会截断当前字串的计算长度
map[(int)*(s+end)] = end+1;//同时,将保存最新重复的元素索引+1 。
} else {//不是相邻重复,
if(start< map[(int)*(s+end)])//首先判断是否之前存在相邻的重复,让我们知道字串计算是否被截断。避免情况:tmmltk这种情况
start = map[(int)*(s+end)];//不存在,就可以直接把start加1,如dvdf,d是重复,start原本指向第一个d,我把start指向 v
map[(int)*(s+end)] = end+1;//同时,将保存最新重复的元素索引+1
maxlength = maxlength>(end-start+1)?maxlength:(end-start+1);//判断字串与之前记录的那个长。
}
}
end++;//开始判断下一个元素
}
return maxlength;
}
}
复杂度分析:
时间复杂度:O(n)
空间复杂度:O(1)
官方题解
1.暴力法
2.窗口滑动
3.优化的窗口滑动。
力扣官方题解链接