LeetCode无重复字符最长子串:自定义Java代码在特定输入下失效原因
无重复字符最长子串代码问题分析
我们要解决的问题是:找出字符串中无重复字符的最长子串长度。LeetCode示例输入s = "abcabcbb",预期输出3(对应子串"abc")。但以下Java代码在处理该输入时无法正常运行,我们来分析原因:
public static int lengthOfLongestSubstring(String s) { String str = ""; int max = 0; for(int i=0; i < s.length(); i++){ if(str.contains(Character.toString(s.charAt(i)))){ if(max < str.length()){ max = str.length(); } i = str.indexOf(s.charAt(i)); str = ""; } else{ str += s.charAt(i); } } if(max < str.length()){ max = str.length(); } System.out.println(str); return max; }
问题根源:索引重置逻辑错误
你的核心思路是遍历字符、维护无重复子串str,遇到重复时更新最长长度、重置索引并清空str。但问题出在重置i时使用了str内部的相对索引,而非原字符串的绝对索引,导致程序陷入循环,无法遍历完整个字符串:
以输入"abcabcbb"为例,执行流程的关键错误节点:
- 初始遍历到
i=3(原字符串第4个字符'a'),此时str="abc",包含'a'。你将i设为str.indexOf('a')=0,然后str清空,for循环的i自增后变为1。 - 接下来遍历
i=1(字符'b'),加入str;i=2(字符'c')加入;i=3(字符'a')加入,str变为"bca"。 - 当遍历到
i=4(字符'b'),str包含'b',你将i设为str.indexOf('b')=0,str清空,i自增后又变为1。 - 此时程序陷入循环:反复处理
i=1到i=4的字符,永远无法推进到i=5及之后的位置,自然无法完成整个字符串的遍历,也无法得到正确结果。
修正思路
要解决这个问题,你需要跟踪当前str在原字符串中的起始绝对索引,而不是仅依赖str的内部相对索引:
- 新增一个
start变量,记录当前无重复子串在原字符串中的起始位置,初始为0。 - 当发现重复字符时,找到该字符在原字符串中的绝对索引:
dupIndex = start + subStr.indexOf(currentChar)(其中subStr是当前子串)。 - 将
start更新为dupIndex + 1,让后续遍历从重复字符的下一个位置开始,同时更新最长长度。
修正后的示例代码(基于你的思路优化):
public static int lengthOfLongestSubstring(String s) { int max = 0; int start = 0; for(int i=0; i < s.length(); i++){ String currentChar = Character.toString(s.charAt(i)); String subStr = s.substring(start, i); if(subStr.contains(currentChar)){ max = Math.max(max, subStr.length()); // 找到重复字符的绝对索引 int dupIndex = start + subStr.indexOf(currentChar); start = dupIndex + 1; } } // 最后检查一次剩余子串 max = Math.max(max, s.length() - start); return max; }
这样就能正确遍历整个字符串,避免循环,并得到正确的最长子串长度。
内容的提问来源于stack exchange,提问作者Aibar Otar
相关产品推荐
相关产品推荐

