File tree Expand file tree Collapse file tree 1 file changed +45
-0
lines changed Expand file tree Collapse file tree 1 file changed +45
-0
lines changed Original file line number Diff line number Diff line change @@ -170,5 +170,50 @@ public class StringUtil {
170
170
return stack. isEmpty();
171
171
}
172
172
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
+
173
218
}
174
219
```
You can’t perform that action at this time.
0 commit comments