注意是子串
本題重要的是明白什么時(shí)候改變左邊界
給定一個(gè)字符串侮繁,請(qǐng)你找出其中不含有重復(fù)字符的 最長(zhǎng)子串 的長(zhǎng)度渣磷。
示例 1:
輸入: "abcabcbb"
輸出: 3
解釋: 因?yàn)闊o(wú)重復(fù)字符的最長(zhǎng)子串是 "abc",所以其長(zhǎng)度為 3。
示例 2:
輸入: "bbbbb"
輸出: 1
解釋: 因?yàn)闊o(wú)重復(fù)字符的最長(zhǎng)子串是 "b",所以其長(zhǎng)度為 1辣往。
示例 3:
輸入: "pwwkew"
輸出: 3
解釋: 因?yàn)闊o(wú)重復(fù)字符的最長(zhǎng)子串是 "wke",所以其長(zhǎng)度為 3殖卑。
請(qǐng)注意站削,你的答案必須是 子串 的長(zhǎng)度,"pwke" 是一個(gè)子序列懦鼠,不是子串钻哩。
來(lái)源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系官方授權(quán)肛冶,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處街氢。
廢話不多說(shuō),先上我寫(xiě)的trash
class Solution {
public int lengthOfLongestSubstring(String s) {
Set set = new HashSet();
for(int i=0;i<s.length();i++)
{
set.add(s.charAt(i));
}
if(set.size()==1) return 1;
int right=0;
int left=0;
int maxlength=0;
int[] freq = new int[200];
for(char c:s.toCharArray()){
freq[c]++;
}
while(right<s.length()){
char charRight = s.charAt(right);
if(freq[charRight]==1 && s.charAt(right)!=s.charAt(left)){
maxlength = maxlength>(right-left+1) ? maxlength:(right-left+1);
}
else if(freq[charRight]>1){
freq[charRight]--;
left++;
}
right++;
}
return maxlength;
}
}
非常凄慘睦袖,只能通過(guò)題目上給的三個(gè)用例珊肃,一提交就錯(cuò)了。
主要原因就在于我不知道如何處理滑動(dòng)窗口的左邊界。
根據(jù)題解的提示伦乔,如果在子串中左邊界未滑動(dòng)前包含了其他重復(fù)字符厉亏,那么就向末尾方向滑動(dòng),舍棄包含重復(fù)字符的子串烈和。
上一下多方參考勉強(qiáng)AC的答案
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length()==0) return 0;
HashMap<Character,Integer> map = new HashMap<>();
int left=0;
int right=0;
int maxlength=0;
while(right<s.length())
//right范圍:「0爱只,s.length()-1」
{
//如果已經(jīng)包含了這個(gè)字符
if(map.containsKey(s.charAt(right)))
//那么left就重新限制左邊界,舍棄重復(fù)字符中出現(xiàn)過(guò)的那個(gè)
left= Math.max(left,map.get(s.charAt(right))+1);
map.put(s.charAt(right),right);
right++;
//對(duì)于已知的子串招刹,記錄一下maxlength
maxlength=Math.max(maxlength,right-left);
}
return maxlength;
}
}