C++求无重复字符最长子串代码指定语法含义问询
无重复最长子串代码问题解答
你贴的是求解字符串最长无重复字符子串的暴力枚举优化版代码,完整修正转义后的代码如下:
class Solution { public: int lengthOfLongestSubstring(string s) { const int n = s.length(); int ans = 0; // 存储最终返回的最大长度 for(int i = 0; i < n; ++i) { vector<int> seen(128); // 对应128个ASCII字符的出现标记,初始值全为0 int j = i; while(j < n && !seen[s[j]]) seen[s[j++]] = 1; ans = max(ans, j - i); } return ans; } };
1. 语法!seen[s[j]]的含义是什么
seen是长度为128的int型数组,专门用来标记当前枚举的子串中是否出现过某个ASCII字符,约定0代表未出现,1代表已出现,初始化时所有元素都是0- C++中char类型本质是整数,存储的是对应字符的ASCII码值,所以
s[j](字符串j位置的字符)可以直接作为下标访问seen数组的对应位置 !是逻辑非运算符,!seen[s[j]]的作用就是判断j位置的字符有没有在当前子串中出现过:没出现过的话seen[s[j]]为0,取非后结果为真,继续循环;出现过的话结果为假,终止循环。
2. 语法seen[s[j++]]=1的运行逻辑是怎样的
执行顺序从左到右,分三步:
- 取j的当前值,获取
s[j]对应的ASCII码作为数组下标,定位到seen数组的对应元素 - 将该元素的值设为1,标记这个字符已经在当前子串中出现过,后续再遇到就会判定为重复
- 最后执行
j的自增操作,j的数值加1,指针移动到下一个字符,为下一轮while循环的判断做准备
这里用的是后置自增j++,只会在当前整条语句执行完成后才对j加1,不会影响本次赋值操作的下标取值
3. 代码中为什么可以用j减去i得到计算结果
这段代码的核心逻辑是枚举所有无重复子串的左端点:
- 外层for循环的i就是当前枚举的无重复子串的左端点
- 内层while循环从i出发向右扩展右端点j,只要字符不重复就一直往右走,循环终止时j的位置要么是第一个重复字符的下标,要么是字符串的总长度n(超出最后一个字符的下标)
- 此时从i到j左闭右开的区间
[i, j)内的所有字符都是不重复的,区间的长度就是j - i,也就是以i为左端点的最长无重复子串的长度 - 每次计算完当前i对应的最大长度后,和全局记录的最大值
ans对比更新,最后得到的ans就是整个字符串的最长无重复子串长度。
内容的提问来源于stack exchange,提问作者DunPushSoHard
相关产品推荐
相关产品推荐

