字节:一面、二面算法题
//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);
}
}