在leetCode上碰到一个题目如下:
我一开始用的双重遍历来做
但是效率低,开销又大。
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
看到了一个别人给出的解法,
一开始看不太懂什么意思
后来想明白了,是什么呢,就是始终以end为边界,利用map的key值唯一的特性,假如重复开始位置就往后移,
其核心思想是通过两个字符之间的间距来实现
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
Map<Character, Integer> map = new HashMap<Character, Integer>();
for (int end = 0, start = 0; end < n; end++) {
char alpha = s.charAt(end);
if (map.containsKey(alpha)) {
start = Math.max(map.get(alpha), start);
}
ans = Math.max(ans, end - start + 1);
map.put(s.charAt(end), end + 1);
}
return ans;
}
}
补充一下,不重复字段的定义是什么
或者换一种说法,怎么才能让字符重复,最简方法是字符串里面含有两个相同的字符,所以求最大值,其实是求两个相同字符之间的最大间距
public int lengthOfLongestSubstring(String s) {
int Max = 0,count =0;
ArrayList arrayList = new ArrayList();
for(int i=0;i<s.length();i++) {
if(arrayList.contains(s.charAt(i))) {
char ch = s.charAt(i);
while((Character)arrayList.get(0)!=ch) {
arrayList.remove(arrayList.get(0));
}//
arrayList.remove(0);
arrayList.add(s.charAt(i));//这里的思想是把不重复的数组放入一个list链表里,然后每次都会计算count,和max比较,假如
count = arrayList.size();//假如重复了,就从链表里删除最先出现的那个元素之前的所有元素。
}else {
arrayList.add(s.charAt(i));
count = arrayList.size();
if(Max <count) {
Max = count;
}
}
}
return Max;
}
这两种思路其实是一样的,实现方法的选择上有分歧而已。