力扣3. 无重复字符的最长子串---滑动窗口 哈希表
3. 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
示例 4:
输入: s = “”
输出: 0
提示:0 <= s.length <= 5 * 10^4s 由英文字母、数字、符号和空格组成
题解:
方法:滑动窗口 哈希表
主要思路是利用哈希表思想来完成判断子串是否会出现重复字符的操作,这样可以大大缩小代码量。即我们先从原数组头部开始形成子串,然后每给他加上一个字符,要先判断加上的字符是否在原来形成的子串中出现过。如果没有出现过则加上然后继续看下一个,若是出现过则此时就需要通过滑动窗口的思想,进行滑动我们的子串的开始下标为与此时对应要加上的字符重复的那个字符对应的下标加一。然后计算一下原先形成的子串的长度。子串开始下标更新后还要重新更新一下我们充当计数器的哈希表的在开始下标前面的部分。然后后面继续以上操作。
图示:
注意的是为了便于每次形成新的开始下标,我们将哈希表存放的值定义为该字符在原数组中对应的下标。
详细可见代码:
代码:
#define max(a,b) ((a)>(b)?(a):(b))int lengthOfLongestSubstring(char * s){ int hah[128];//哈希表 memset(hah,-1,128*sizeof(int));//先都初始化为-1 int num = 0; int start = 0;//开始的起点 int num2 = 1; int num3 = 0; int x; if(strlen(s)==0) return 0; if(strlen(s)==1) return 1; for(int i=0;i<strlen(s);i ) { if(hah[s[i]]==-1)//一旦还没有碰到该字符s[i]时 { hah[s[i]]=i;//储存对应元素下标 num3 ; if(i==strlen(s)-1)//这是为了避免一直到末尾都不用更新开始下标的情况,即避免了“aab”类情况 //即可能会漏算最后形成的一个子串的长度,所以我们将这个长度与前面那些子串长度进行比较 { x=i-start 1; return max(x,num2); } } else//一旦哈希表碰到了两次同样的字符时 { num = i-1-start 1;//计算一下原先形成的子串长度 num2 = max(num2,num);//储存更大的子串长度 start = hah[s[i]] 1;//更新子串开始下标 for(int j=1;j<128;j ) { if(hah[j]<start)//将哈希表中每个字符储存的下标在新开始下标前面的部分的元素都初始化为原先的样子 { hah[j]=-1; } } hah[s[i]]=i;//原先这个没有计数,现在给他计数一下,因为他是包含在新形成的子串里的 } } if(num3==strlen(s))//若一直没有更新子串开始下标,即直接本身数组便是答案的情况 { return num3; } else { return num2; }}
赞 (0)