您的位置:首页 > 其它

Leetcode 159 & 340 Longest Substring with At Most Two/K Distinct Characters

2016-10-01 03:12 393 查看


159. Longest Substring with At Most Two Distinct Characters

Total Accepted: 16833 Total Submissions: 44512 Difficulty: Hard

Given a string, find the length of the longest substring T that contains at most 2 distinct characters.
For example, Given s = 
“eceba”
,
T is "ece" which its length is 3.

Hide Company Tags
 Google

Hide Tags
 Hash Table Two
Pointers String

Hide Similar Problems
 (M) Longest Substring Without Repeating Characters (H)
Sliding Window Maximum (H) Longest Substring with At Most K Distinct Characters

自己思路:

一开始:

记录一个start位置,记录一个结果变量res,再用一个hashmap保存该char出现的index,再用一个count变量计数。

从左到右一遍,每次更新结果res = Math.max(res, cur - start + 1):

1. 如果map中有该字符,说明出现过,重写value。

2. 如果map中没有该字符,但是count < 2,加入map,count++。

3 如果map中没有字符并且count为2,说明需要剔除一个字符。要求的是substring,必须是连续的。从cur-2位置开始,到之前的start,如果字符!= cur-1处的字符,则删除break循环。(例如:ccaabbb)

然后就发现其实map是没有意义的,我们关心的是这个元素出现过没有,而不是它在哪出现。于是换成了hashset,这样count变量也可以省去了。

public class Solution { / 26ms
public int lengthOfLongestSubstringTwoDistinct(String s) {
if(s == null || s.length() == 0) return 0;
int start = 0;
int res = Integer.MIN_VALUE;
int cur = 0;
char[] ss = s.toCharArray();
Set<Character> set = new HashSet<Character>();

while(cur < ss.length){
if(set.contains(ss[cur])){
set.add(ss[cur]);
}else if(set.size() < 2){
set.add(ss[cur]);
}else{
for(int i = cur - 2; i >= start; i--){
if(ss[i] != ss[cur - 1] && set.contains(ss[i])){
set.remove(ss[i]); start = i + 1; break;
}
}
set.add(ss[cur]);
}
res = Math.max(res, cur - start + 1);
cur++;

}
return res;
}
}


别人的解法,参考这里:count == 0 则 map删除该key,确实秒。

public class Solution { // 39ms
public int lengthOfLongestSubstringTwoDistinct(String s) {
Map<Character, Integer> map = new HashMap<>();
int left = 0;
int i = 0;
int maxLen = 0;
while (i < s.length()) {

// 根据右指针指的当前字符更新map
char c = s.charAt(i);
if (!map.containsKey(c)) {
map.put(c, 1);
} else {
map.put(c, map.get(c) + 1);
}

// 移动左指针,直到map中字符数量降至规定数量
while (map.size() > 2) {
char leftChar = s.charAt(left);
if (map.containsKey(leftChar)) {

// 注意会有重复元素,所以先减小次数,只有次数降至0,才删除元素
map.put(leftChar, map.get(leftChar) - 1);
if (map.get(leftChar) == 0) {
map.remove(leftChar);
}
}
left++;
}
maxLen = Math.max(maxLen, i - left + 1);
i++;
}
return maxLen;
}
}



340. Longest Substring with At Most K Distinct Characters

Total Accepted: 7676 Total Submissions: 19611 Difficulty: Hard

Given a string, find the length of the longest substring T that contains at most k distinct characters.
For example, Given s = 
“eceba”
 and k = 2,
T is "ece" which its length is 3.

Hide Company Tags
 Google

Hide Tags
 Hash Table String

Hide Similar Problems
 (H) Longest Substring with At Most Two Distinct
Characters

自己思路:

沿用上面的代码。之前2个时候只需要只需要探测cur-1位置之前是否有连续的字符串就行了(aab, aaab, aaaab, b是cur位置)。

现在是k个,结果问题来了。

首先是ab无法i - 2,然后其他各test case也是各种多一少一。

于是决定这样:

清除set,从当前位置开始,往前遍历,加入元素直到k个,这时候更新start和res。当然这样就变成了O(NK)。

public class Solution { // 64 ms
public int lengthOfLongestSubstringKDistinct(String s, int k) {
if(s == null || s.length() == 0 || k == 0) return 0;

int start = 0;
int res = Integer.MIN_VALUE;
int cur = 0;
char[] ss = s.toCharArray();
Set<Character> set = new HashSet<Character>();

while(cur < ss.length){
if(set.contains(ss[cur])){
set.add(ss[cur]);
}else if(set.size() < k){
set.add(ss[cur]);
}else{
set.clear();
int i = cur;
while(set.size() < k || set.contains(ss[i])){
if(!set.contains(ss[i])) set.add(ss[i]);
i--;
}
start = i + 1;
}
res = Math.max(res, cur - start + 1);
cur++;
}
return res;
}
}


别人的思路,把之前的2换成k就行:

public class Solution { // 65ms
public int lengthOfLongestSubstringKDistinct(String s, int k) {
Map<Character, Integer> map = new HashMap<>();
int left = 0;
int i = 0;
int maxLen = 0;
while (i < s.length()) {

// 根据右指针指的当前字符更新map
char c = s.charAt(i);
if (!map.containsKey(c)) {
map.put(c, 1);
} else {
map.put(c, map.get(c) + 1);
}

// 移动左指针,直到map中字符数量降至规定数量
while (map.size() > k) {
char leftChar = s.charAt(left);
if (map.containsKey(leftChar)) {

// 注意会有重复元素,所以先减小次数,只有次数降至0,才删除元素
map.put(leftChar, map.get(leftChar) - 1);
if (map.get(leftChar) == 0) {
map.remove(leftChar);
}
}
left++;
}
maxLen = Math.max(maxLen, i - left + 1);
i++;
}
return maxLen;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Hash Table String