原题网址:https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/
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.
方法:使用直方图统计字符出现次数,如果是首次出现则distinct字符数加1.
public class Solution {
public int lengthOfLongestSubstringKDistinct(String s, int k) {
if (s == null) return 0;
int from = 0;
int[] histogram = new int[256];
int distinct = 0;
char[] sa = s.toCharArray();
int max = 0;
for(int i=0; i<sa.length; i++) {
if (histogram[sa[i]] == 0) distinct ++;
histogram[sa[i]] ++;
while (distinct > k) {
histogram[sa[from]] --;
if (histogram[sa[from]] == 0) distinct --;
from ++;
}
max = Math.max(max, i-from+1);
}
return max;
}
}
另一种实现:
public class Solution {
public int lengthOfLongestSubstringKDistinct(String s, int k) {
int from = 0;
int max = 0;
char[] sa = s.toCharArray();
int[] f = new int[256];
int d = 0;
for(int i=0; i<sa.length; i++) {
if (f[sa[i]]++ == 0) d++;
while (d>k && from<=i) {
if (f[sa[from]]==1) d--;
f[sa[from++]]--;
}
max = Math.max(max, i-from+1);
}
return max;
}
}
进一步简化:
public class Solution {
public int lengthOfLongestSubstringKDistinct(String s, int k) {
if (k <= 0) return 0;
int[] f = new int[256];
int distinct = 0;
char[] sa = s.toCharArray();
int from = 0;
int max = 0;
for(int i=0; i<sa.length; i++) {
if (f[sa[i]] ++ == 0) distinct ++;
while (distinct > k) {
if (--f[sa[from++]] == 0) distinct --;
}
max = Math.max(max, i-from+1);
}
return max;
}
}