Skip to content

Commit 90b8c9c

Browse files
author
dai
committed
length Of Longest Substring
1 parent 0f3ca10 commit 90b8c9c

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

27-算法面试专题-字符串.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,5 +170,50 @@ public class StringUtil {
170170
return stack.isEmpty();
171171
}
172172

173+
174+
/**
175+
* 6、求一个字符串无重复最长子串
176+
177+
* 子串和子序列的区别,子串必须要连续,子序列不一定要连续。
178+
* 遇到子串和子序列的问题,可以按照一种经典思路:
179+
* 按照i位置结尾的情况下答案是什么?求所有可能的结尾即可,所有位置结尾的答案都求出,最大的就是我们的目标答案
180+
* 时间复杂度O(N),空间复杂度O(1),由于申请的空间是固定长度256
181+
* @param s
182+
* @return
183+
*/
184+
public static int lengthOfLongestSubstring(String s) {
185+
// base case 过滤无效参数
186+
if (s == null || s.equals("")) {
187+
return 0;
188+
}
189+
190+
char[] str = s.toCharArray();
191+
int[] map = new int[256];
192+
// 辅助数组。保存字符出现的位置,字符的范围为可显示字符0~127,扩展ascii字符128~255
193+
for (int i = 0; i < 256; i++) {
194+
// 默认所有的字符都没出现过
195+
map[i] = -1;
196+
}
197+
// i位置往左推,推不动的位置第一个因素是再次遇到了i位置上的元素,第二个因素是i-1位置当初推了多远。
198+
// 这两个因素的限制,哪个限制位置离当前i位置近,就是当前字符i最远推到的位置,map[i]
199+
// 收集答案。len是收集全局的最大长度
200+
int len = 0;
201+
int pre = -1; // i-1位置结尾的情况下,往左推,推不动的位置是谁。用来每次保存i之前一个位置的答案
202+
int cur = 0;
203+
for (int i = 0; i != str.length; i++) {
204+
// i位置结尾的情况下,往左推,推不动的位置是谁
205+
// pre (i-1信息) 更新成 pre(i 结尾信息)
206+
// 上次推不动的,和当前字符上次出现的位置map[str[i]]的位置,取大的
207+
pre = Math.max(pre, map[str[i]]);
208+
// 找到了当前推不动的位置,当前不重复子串的长度就是i-pre
209+
cur = i - pre;
210+
// 全局最大的子串长度,是否被更新,决定是否要收集
211+
len = Math.max(len, cur);
212+
// 更新当前字符出现的位置是当前位置
213+
map[str[i]] = i;
214+
}
215+
return len;
216+
}
217+
173218
}
174219
```

0 commit comments

Comments
 (0)