查找最长无重复的子字符串
题目描述:给定一个字符串,查找最长无重复的子字符串的长度
例子:
- 给定字符串 “abcabcbb”,最长无重复子字符串为“abc”,长度为3
- 给定字符串“bbbbb”,最长无重复子字符串为“b”,长度为1
- 给定字符串“pwwkew”,最长无重复子字符串为“wke”,长度为3
Given a string, find the length of the longest substring without repeating characters.
Examples:
- Given “abcabcbb”, the answer is “abc”, which the length is 3.
- Given “bbbbb”, the answer is “b”, with the length of 1.
- Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
算法设计一:暴力求解 (Brute Force)
采用暴力求解,但是时间超时(Time Limit Exceeded),不是最优算法。
public static int lengthOfLongestSubstring(String s) {
int n = s.length();
int ans = 0;
for (int i = 0; i < n; i++)
for (int j = i + 1; j <= n; j++)
if (allUnique(s, i, j)) ans = Math.max(ans, j - i);
return ans;
}
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;
}
完整的代码如下:
package com.bean.algorithmbasic;
import java.util.HashSet;
import java.util.Set;
public class LongestSubStringNoRepeat {
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* Given a string, find the length of the longest substring without repeating characters.
* Examples:
* Given "abcabcbb", the answer is "abc", which the length is 3.
* Given "bbbbb", the answer is "b", with the length of 1.
* Given "pwwkew", the answer is "wke", with the length of 3.
* Note that the answer must be a substring,
* "pwke" is a subsequence and not a substring.
* */
String strDemo="abcabcbb";
int result=lengthOfLongestSubstring(strDemo);
System.out.println(result);
}
public static int lengthOfLongestSubstring(String s) {
int n = s.length();
int ans = 0;
for (int i = 0; i < n; i++)
for (int j = i + 1; j <= n; j++)
if (allUnique(s, i, j)) ans = Math.max(ans, j - i);
return ans;
}
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;
}
}
算法设计二:设定滑动窗口(Sliding Window)
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int ans = 0, i = 0, j = 0;
while (i < n && j < n) {
// try to extend the range [i, j]
if (!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
ans = Math.max(ans, j - i);
}
else {
set.remove(s.charAt(i++));
}
}
return ans;
}
算法设计三:对滑动窗口的优化算法
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
Map<Character, Integer> map = new HashMap<>(); // current index of character
// try to extend the range [i, j]
for (int j = 0, i = 0; j < n; j++) {
if (map.containsKey(s.charAt(j))) {
i = Math.max(map.get(s.charAt(j)), i);
}
ans = Math.max(ans, j - i + 1);
map.put(s.charAt(j), j + 1);
}
return ans;
}
(完)