1010
1111如果第i个字符之前出现过呢?找到该字符上次出现的位置preIndex,当前位置i - preIndex就得到这两个重复字符之间的距离,设为d。此时有两种情况
1212
13- - 如果`d <= f(i-1)`,说明当前重复字符必然在f(i-1)所对应的字符串中,比如’bdcefgc‘,当前字符c前面出现过了,preIndex为2,此时`d = 6 -2 = 4` ,小于` f(i -1) = 7 (bdcefg)`我们只好丢弃前一次出现的字符c及其前面的所有字符,得到当前最长不含重复字符的子字符串为’efgc‘,即`f(i) = 4`, 多举几个例子就知道,应该让`f(i) = d`;
13+ - 如果`d <= f(i-1)`,说明当前重复字符必然在f(i-1)所对应的字符串中,比如’bdcefgc‘,当前字符c前面出现过了,preIndex为2,此时`d = 6 -2 = 4` ,小于` f(i -1) = 6 (bdcefg)`我们只好丢弃前一次出现的字符c及其前面的所有字符,得到当前最长不含重复字符的子字符串为’efgc‘,即`f(i) = 4`, 多举几个例子就知道,应该让`f(i) = d`;
1414
1515- 如果`d > f(i-1)`, 这说明当前重复字符必然在f(i-1)所对应的字符串**之前**,比如`erabcdabr`当前字符r和索引1处的r重复,`preIndex =1, i = 8,d = 7`。而`f(i -1) = 4 (cdab)`,此时直接加1即可,即`f(i) = f(i-1) +1`
1616
2121package Chap5;
2222
2323public class LongestSubstring {
24- public int findLongestSubstring(String str) {
24+ public int lengthOfLongestSubstring(String str) {
25+ if (str == null || str.length() == 0) return 0;
2526 int curLen = 0;
2627 int maxLen = 0;
2728 // 0~25表示a~z,position[0] = index,表明a上次出现在index处
28- int[] position = new int[26 ];
29- for (int i = 0; i < 26 ; i++) {
29+ int[] position = new int[256 ];
30+ for (int i = 0; i < 256 ; i++) {
3031 position[i] = -1;
3132 }
3233
3334 for (int i = 0; i < str.length(); i++) {
34- int preIndex = position[str.charAt(i) - 'a' ];
35+ int preIndex = position[str.charAt(i)];
3536 // 字符第一次出现,或者d > f(i -1)
3637 if (preIndex == -1 || i - preIndex > curLen) curLen++;
3738 // d <= f(i -1)
3839 else {
39- if (curLen > maxLen) maxLen = curLen;
4040 curLen = i - preIndex;
4141 }
4242 // 记录当前字符出现的位置
43- position[str.charAt(i) - 'a'] = i;
43+ position[str.charAt(i)] = i;
44+ if (curLen > maxLen) maxLen = curLen;
4445 }
45- if (curLen > maxLen) maxLen = curLen;
4646 return maxLen;
47+
4748 }
4849}
4950
5051```
5152
52- 用了一个数组position代替哈希表,记录'a' ~ 'z'每个字符上次出现的位置 ,能以O(1)的时间完成,先要将position中的值全初始化为-1,因为上次出现的位置可能含有索引0。 curLen就是上面说到的$f(i -1)$
53+ 用了一个数组position代替哈希表,记录每个字符上次出现的位置 ,能以O(1)的时间完成,先要将position中的值全初始化为-1,因为上次出现的位置可能含有索引0。 curLen就是上面说到的$f(i -1)$
5354
5455如果某个字符第一次出现,那么它上次出现的位置preIndex为-1。当前最长不重复子字符串直接加1。
5556
@@ -59,4 +60,4 @@ public class LongestSubstring {
5960
6061by @sunhaiyu
6162
62- 2018.1.24
63+ 2018.1.24
0 commit comments