《2018年2月22日》【连续134天】
标题: Longest Substring Without Repeating Characters的方法;
内容:
1.昨天的题目:
阅读了它的解题思路:
方法一:
利用set容器的唯一性,来判断字符串是否有重复元素,然后枚举所有的子字符串,缺点的耗时,程序超时:
class Solution {
public static boolean allunique(String s,int start, int end) {
Set<Character> set =new HashSet<>();
boolean truth=true;
for(int i=start;i<end;i++)
{
Character chars =s.charAt(i);
if(set.contains(chars)) truth=false; //通过set容器的唯一性判断子字符串是否有重复元素;
set.add(chars);
}
return truth;
}
public static int lengthOfLongestSubstring(String s) { //本体
int length =s.length();
int result =0;
String longest="";
for(int i=0;i<length;i++)
for(int j=i+1;j<=length;j++)
{
if(allunique(s,i,j)) longest=s.substring(i, j);
result =Math.max(result, longest.length());
}
return result;
}
}
方法二:滑动窗口(sliding window)
简单来[i,j)向右滑动一个就变成了[i+1,j+1);
因为在方法一中我们重复的检查了许多子字符串,如果是s[i,j)是无重复子字符串,那么只需检查第j个元素是否在前面重复,
所以我们用滑动窗口来判断,每次见j向右移一个,直至重复,就让i向右移一格:
public static int lengthOfLongestSubstring(String s) { //本体
int length =s.length();
int result =0;
int i=0;
int j=0;
Set<Character> set =new HashSet<>();
while (i<length && j<length)
{
if(!set.contains(s.charAt(j)))
{
set.add(s.charAt(j++));
result=Math.max(result, j-i);
}
else
set.remove(s.charAt(i++));
}
return result;
}
方法三:
如果用滑动窗口的话,如果j出现了重复,i可以直接移到与第j位重复元素s的右边,
即[i,j)->[s+1,j),而通过HashMap可以直接确定s的位置;
public class Solution {
public static int lengthOfLongestSubstring(String s) {
int length =s.length();
int result =0;
int i=0;
int j=0;
HashMap<Character, Integer> map = new HashMap<>();
for(;j<length;j++)
{
if(map.containsKey(s.charAt(j)))
i =Math.max(map.get(s.charAt(j)), i);
result =Math.max(result, j-i+1);
map.put(s.charAt(j), j+1);
}
return result;
}
}