小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
无重复字符的最长字符串
该题出自力扣的第三题,无重复字符的最长字符串(中等题);解法消化于力扣评论区大神;
审题
-
给出一个字符串,计算出该字符串内无重复字符的最长字符串
-
方法一:双指针遍历 (×)
- 记录最大长度,A指针指向头部,B指针指向下一节点,B指针向后移动
- 遍历A指针及走过至B指针的字符,若存在重复,则A指针移动到重复字符的下一位
- 时间复杂度:O(n²),空间复杂度的话:O(n)
-
方法二:记录位置与起点进行推移 (√)
- 利用ASSIC值的长度,定义一个长度为128的整型数组
- 定义两个参数,最长字符串长度、最长字符串长度起点
- 循环字符串内的字符,记录当前字符的ASSIC值
- 起点取 当前起点与数组内当前字符的ASSIC值作为下标的最大值
- 长度取 当前长度与计算长度的最大值
- 时间复杂度:O(n);空间复杂度:O(1)
-
编码实现
public int lengthOfLongestSubstring(String s) {
//记录 字符出现的位置
int[] last = new int[128];
//字符的长度
int n = s.length();
//记录无重复长度
int res = 0;
//无重复字符的起点
int start = 0;
for(int i =0;i<n;i++){
//获取当前字符的ASSIC值
int index = s.charAt(i);
//如果有重复的话,起点指针往前推(沿用数组内的值)
start = Math.max(start,last[index]);
//如果有重复的话,当前字符所在i 减去 start(起点),例:i = 6,start = 5,加1,就是长度2
res = Math.max(res,i-start+1);
//与start 形成闭环,存放位置(从1开始计算),start直接取,即下一位
last[index] = i+1;
}
return res;
}