好难理解的题_(:з」∠)_
找到字符串中最长的无重复子串
输出最长无重复子串长度
滑动窗口
int lengthOfLongestSubstring(char * s){
int table[0xFF]={-1};
int maxlen=0;
int comp=0;
int start=0;
int ascii;
int i=0;
while(s[i]!='\0')
{
ascii=s[i];
if(table[ascii]>=start)
{
maxlen=(i-start)>(maxlen)?(i-start):(maxlen);
start=table[ascii]+1;
}
table[ascii]=i;
++i;
}
maxlen=(i-start)>(maxlen)?(i-start):(maxlen);
return maxlen;
}
用哈希查找完成
上程序有误处理不了输入为“”以及“ ”的情况
正确示例
源码:
int lengthOfLongestSubstring(char * s) {
int table[0xFF];
memset(table, -1, sizeof(table));
int maxlen = 0;
int idx = 0;
int startidx = 0;
int findidx = 0;
int ch;
while ((ch = s[idx]) != '\0') {
findidx = table[ch];
if (findidx >= startidx) {
int len = idx - startidx;
maxlen = len > maxlen ? len : maxlen;
startidx = findidx + 1;
}
table[ch] = idx;
++idx;
}
int len = idx - startidx;
maxlen = len > maxlen ? len : maxlen;
return maxlen;
}
作者:ithewei
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/cyu-yan-hua-dong-chuang-kou-si-xiang-cha-biao-fa-j/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
带注释版本:
int lengthOfLongestSubstring(char * s) {
int table[0xFF];//即十进制下255
memset(table, -1, sizeof(table));//把表中元素置为-1
int maxlen = 0;//最长不重复子列长度
int idx = 0;//从左往右遍历过程中使用的循环变量
int startidx = 0;
//startidx为从左往右遍历字符串时,上一次出现的重复字符位置
//且总要保证这个位置最靠右
//例如abcbdecb
//第二个b出现时,在执行if语句完结后startidx等于2,即b首次出现的位置
//第二个c出现时,if后startidx为3
//第三个b出现时,if后startidx为4,即第二个b出现的位置
//例如abcbdeca
//第二个a出现时,startidx不改变
//因为上一个a的位置为1,并不如第一个c的位置(为3)靠右
int findidx = 0;
//用于提取出正在操作的字符在256字符表中的值
int ch;
//用ch直接取出字符串中字符的ASCII码,即使用下面的赋值语句ch=s[idx]
while ((ch = s[idx]) != '\0') {
findidx = table[ch];
if (findidx >= startidx) {
int len = idx - startidx;
maxlen = len > maxlen ? len : maxlen;
startidx = findidx + 1;
}
//此处说明startidx的用意
//更新最新出现的重复字符位置
//因为可能有多种重复字符,如上例中abcbdecb
//第二个c出现时更新为3,因为c是最新出现的重复字符
//第三个b出现时更新为4
//b虽然已重复出现过一次,可是在c第一次重复之后b发生了第二次重复
//故更新为4,即第二个b的位置
//当遍历到下一个位置时,考虑任意一个在startidx左边的位置
//把当前遍历所处的位置记为b,任意一个startidx左边的位置记为a
//从a到b中,必有startidx所指的字符重复
//因此所有startidx左边的位置均是无效的,即不会威胁到当前取出的最大长度
//为加强理解,试问为何使用findidx>startidx而不用findidx>-1?
//答:需要更新startidx的值,但并不是每次出现重复都要更新
//且所有在startidx之前发生的重复都不用考虑
//如例abcbdeca中,当遍历至第二个c时,startidx更新为3
//在第三个字符之前发生的重复均无效,即在第二个a出现时,并不把它视为重复
//再举例abefgcbdecaefg
//第二个c出现之后,所有第6个字符(第一个c)之前出现的字符都不算数
//第6个字符(第一个c)之后的abefg均视为第一次出现
table[ch] = idx;
++idx;
}
int len = idx - startidx;
maxlen = len > maxlen ? len : maxlen;
//此处重写用于更新maxlen,考虑到不改变startidx的情况下仍有可能改变maxlen
//如上例中abcbdeca
//虽然第二次出现a时startidx不更新,但实际的maxlen已经更新(bdec变为bdeca)
return maxlen;
}
赋值语句的返回值为等号右边的值
即赋给的值