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 {
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```
You can’t perform that action at this time.
0 commit comments