- 题目
求最长的无重复字符的子串
- 思路1
- 最长无重复子串肯定包含在两个重复字符之间,用len保存当前最长的子串。如果某两个重复字符之间的子串长于len,则给len赋值这个新的长度。
- 定义一个标志位数组,大小为128,表示从空格到abcd……xyz到ABC……XYZ,都用ASCII码表示,某一个字符出现,就在对应的位置1,比如出现a,就在数组的第65位置1.ASCII码为0的为' ',用a-' '得到a的ASCII码值.
- 思路2
BF方法的时间复杂度是O(n^3),对每个substring都看看是不是有重复的字符,找出其中最长的。优化的方法是通过动态规划。
- 思路3
- 线性的方法,常用方法,基本思路是维护一个窗口,每次关注窗口中的字符串,每次判断中,左窗口和右窗口选择其一向前移动。
- 正常情况下移动右窗口,如果没有出现重复则继续移动有窗口,如果发现重复字符,则说明当前窗口中的串已经不满足要求,继续移动右窗口不可能得到更好的结果,此时移动左窗口,直到不再有重复字符为止。
- 代码
package leetcode.longestsubstringwithoutRepeatingCharacters;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
public class LongestSubstringWithoutRepeatingCharacters {
static int[] last = new int[128];//last数组用于保存新出现的字符的下标
public static int lengthOfLongestSubstring(String s) {
int start = 0;
int len = 0;
char[] w = new char[s.length()];//将字符串转换为字符数组
w = s.toCharArray();
System.out.println(w[1]-' ');
for (int i = 0; i < 128; i++)
last[i] = -1;// last数组用于保存新出现的字符的下标,一开始全部初始化为-1
for (int i = 0; i < s.length(); ++i) {
if (last[w[i] - ' '] >= start) { // 当前这个字符出现过
if (i - start > len)
len = i - start;
start = last[w[i] - ' '] + 1; // 从这个字符首次出现的位置+1,重新扫描,相当于把前面抛开前面的字符串不谈
}
last[w[i] - ' '] = i;// 更新当前字符的下标
}
if (len > s.length() - start)// 针对没有重复字符的字符串
return len;
else
return s.length() - start;
}
public static void main(String args[]) {
String s = "aabcbab";
int l = lengthOfLongestSubstring(s);
System.out.println(l);
}
}