LeetCode0003-最长子串
字节:一面、二面算法题
//https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
// // 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
//自己卡在了: 没有想到用hashset来判重
import java.util.HashMap; import java.util.HashSet; import java.util.Map; //自己卡在了: 没有想到用hashset来判重 //方法一:暴力破解法 找出所有的子字符串,然后挨个判断 public class Num003_longestSubstring { public int lengthOfLongestSubstring(String s) { int ans=0; for(int i =0;i<s.length();i++){ for(int j=i+1;j<s.length();j++){ // 穷举所有子字符串,判断子字符串中是否有重复值,没有的话,更新最大值 if(isDup(s,i,j)) { ans = Math.max(ans,j-i+1); } } } return ans; } public Boolean isDup(String s,int start,int end){ // 用hashset判断是否有重复的字符,有了的话contains方法返回true HashSet<Character> re = new HashSet<Character>(); for(int i= start;i<= end;i++){ Character ch = s.charAt(i); if(re.contains(ch)){ // 有重复,就返回false return false; } // 【注意这一步!】如果是自己,可能就先add了--》先判断是否重复,不重复的话再入set re.add(ch); } return true; } //方法二:移动窗口 public static int lengthOfLongestSubstring2(String s) { int n = s.length(); int ans =0; Map<Character,Integer> result = new HashMap<>(); for(int start =0,end=0;end<n;end++){ Character cr = s.charAt(end); if(result.containsKey(cr)){ // //核心点。即:确认好新的子串开始的下标。最后子串的长度是根据 子串下标的差得到的 // 自己的问题就出现在这里,i其实是不能回头的。 // 如:abba,发现第二个b的时候,i已经从原先的0移动到了2(指向第二个b),再次发现第二个a的时候,a原先对应的result.get(cr)+1 =1; // 如果直接用下面条件判断的话,i又返回去了。所以需要用max来限定一下起始位置 // (自已一直陷在map没有除去开始位置的坑里,其实不用,只需要记录好子串开始的位置就可以,相当于纯靠位置,不靠内容去判断 // i=result.get(cr)+1; start = Math.max(start,result.get(cr)+1); } result.put(cr,end); ans= Math.max(ans,end-start+1); } return ans; } public static void main(String[] args) { String s = "abba"; int n = lengthOfLongestSubstring2(s); } }