
- 由于要无重复字符,我们必然要想办法记录已使用的字符来确保唯一,那就自然想到两种办法解决
- 用容器记录已使用的字符,每添加新字符时,都判断是否有重复。
- 维持一段不重复序列,每天添加新字符,要遍历判断是否和不重复序列不同
- 下面是使用HashMap来记录已使用的字符,Key代表字符,Value代表字符所在下标
- 之所以这样,是可以通过下标判断它是否被抛弃了,因为重复字符会导致之前的字符失效。
因此需要几个变量来维持
- max记录最长不重复字符的长度
- cur记录当前维持的不重复字符的长度
- startIndex记录当前不重复字符的开始下标
- map记录已使用的字符
public int lengthOfLongestSubstring(String s) {int max = 0, len = s.length(), cur = 0, startIndex = 0;Map<Character, Integer> map = new HashMap<>();for (int i = 0; i < len; i++) {Character ch = s.charAt(i);//这里需要判断字符是否使用和字符是否已经失效,失效字符可以重新添加到不重复字符中if (!map.containsKey(ch) || map.get(ch) < startIndex) {cur++;} else {Integer index = map.get(ch);//更新重复字符导致的丢失后的剩余长度cur -= (index - startIndex);//更新不重复字符的开始下标startIndex = index + 1;}max = Math.max(cur, max);//不管是否重复,用最新值代替map.put(ch, i);}return max;}
需要使用左右指针维持一个不重复序列
- 因此需要变量
- l:左指针
- r:右指针
- max记录最长不重复字符的长度
public int lengthOfLongestSubstring(String s) {int l = 0, r = 1, len = s.length(), max = 0;for (int i = 1; i < len; i++) {char ch = s.charAt(i);//遍历判断不重复序列中是否有该字符for (int j = l; j < r; j++) {//存在,则设置新的左指针if (s.charAt(j) == ch) {l = j + 1;break;}}r = i + 1;max = Math.max(max, r - l);}//需要特殊处理一下边界问题return max = len == 1 ? 1 : max;}
