1.Longest Substring Without Repeating Characters
题目要求:给出一个字符串,要求输出最长的不重复字符床的长度。
如:“abcabcabc”
输出:3
- 解法一
分析:最笨的办法就是将该字符串能切割的所有可能都列出来。然后比较其满足条件的长度。在将字符添加集合前先进行判断,如果含有该字符,直接返回false,进行下轮判断。返回true时,就代表这个字符串中不含有相同的字符,这时调用math中的max方法,找出字符串中的最大值。
public class Longest_Substring_Without_Repeating_Characters {
public static void main(String[] args) {
String s = "abcabc";
int length = s.length();
int answer = 0;
for(int i = 0; i < length; i++) {
for(int j = i + 1; j <= length; j++) {
if(allUnique(s, i, j)) answer = Math.max(answer, j - i);
}
}
System.out.println(answer);
}
// 寻找字符串中字符不重复的字符串
public static boolean allUnique(String s, int start, int end) {
Set<Character> set = new HashSet<>();
for(int i = start ; i < end; i++) {
Character ch = s.charAt(i);
if(set.contains(ch)) return false;
set.add(ch);
}
return true;
}
}
时间复杂度:首先这里的main函数中有一个双重for循环,然后最内层的for循环中又嵌套了一个allUnique函数,这个函数里面还有一个for循环,所有这个算法的时间复杂度大致为O(n三次方)
- 解法二
分析:可以采用一种叫移动窗(可能不了解,但看了代码就知道这代码的神奇之处了)的方法,先说下大体的思路,假设有一个长度可变的窗户,它从字符串的开头开始,如果字符不在窗户中,就将字符添加到窗户中。如果下个字符在窗户中,就将窗户中的第一个字符移出来。每次更新窗户中的长度,确保其值最大。最终返回最大值即为所求。
public class Longest_Substring_Without_Repeating_Characters {
public static void main(String[] args) {
String s = "abcabc";
int length = s.length();
int answer = 0, i = 0, j = 0;
Set<Character> set = new HashSet<>();
while(i < length && j < length) {
// 集合中没有该字符 加入
if(!set.contains(s.charAt(j))) {
set.add(s.charAt(j++));
answer = Math.max(answer, j - i);
}else {
// 集合中含有该字符 移除头部元素
set.remove(s.charAt(i++));
}
}
System.out.println(answer);
}
总结:
(1)时间复杂度:O(n)。
(2)利用移动窗的功能大大减少了循环的次数,高效的筛选出了没有重复字符的字串。