给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:
输入: s = "" 输出: 0
思路:
-
使用
HashMap
存储字符及其位置,key
为字符,value
为字符出现的位置; -
使用
start
记录子字符串的起始位置; -
使用
max
记录符合条件的子字符串的最大长度:max = Math.max(max, index - start + 1)
; -
遍历字符串中的每个字符,用
index
记录位置,取到每个字符s.charAt(i)
,先判断HashMap
中是否已存在此字符; -
如果不存在此字符则将其存入
HashMap
:
例如字符串abcda
,HashMap
中依次存入(a, 0)
、(b, 1)
、(c, 2)
、(d, 3)
. -
如果存在此相同字符:
1、说明已找到一个符合条件的子字符串(起始位置为start
,终止位置为index
的上一个位置);
例如字符串abcdaea
,找到第五个字符a
为已存在字符,则找到符合条件的子字符串为abcd
;
例如字符串abcddea
,找到第五个字符d
为已存在字符,则找到符合条件的子字符串为abcd
.
2、在HashMap
中找到此字符的value
值(也就是位置),记为p
,更新子字符串的起始start
位置:如果start >= p + 1
,则仍保留start
位置,否则更新start = p + 1
;
例如字符串abcddea
,找到相同字符d
,第一次出现位置为3
,start
值为0
,则应更新start
为4
.
例如字符串abcdaea
,找到相同字符a
,第一次出现位置为0
,start
值为0
,则应更新start
为1
.
3、更新此字符在HashMap
中的value
值,即更新它的位置. -
遍历结束后,返回
max
的值. -
实现代码
import java.util.HashMap; class Solution { public int lengthOfLongestSubstring(String s) { if (s.length() == 0) { return 0; } HashMap<Character, Integer> map = new HashMap<>(); int max = 0; for (int index = 0, start = 0; index < s.length(); ++index) { if (map.containsKey(s.charAt(index))) { start = Math.max(start, map.get(s.charAt(index)) + 1); } map.put(s.charAt(index), index); max = Math.max(max, index - start + 1); } return max; } }
方法二:
class Solution { public int lengthOfLongestSubstring(String s) { HashMap<Character,Integer> hm = new HashMap<>(); int max = 0; int j = 0; for (int i = 0; i <s.length() ; i++) { if(hm.containsKey(s.charAt(i))) { j = Math.max(hm.get(s.charAt(i))+1,j); //if input="abbabc" //when i = 3, s.chatAt(3) == 'a' , //we will found last 'a' appears at index 0, //but we should not update j from 2 ('b') to 0 ('a'), //because here although the 'a' is in hashMap, but it appears before 'b'. } //i到j没有重复的字母,所以+1 //写到if外,因为可能该串本身就没有重复的字母,以及串首与串尾也要考虑 max = Math.max(i-j+1,max); hm.put(s.charAt(i), i); }; return max; } }