340. Longest Substring with At Most K Distinct Characters

51 篇文章 0 订阅
Description

Given a string, find the length of the longest substring T that contains at most k distinct characters.

Example 1:

Input: s = “eceba”, k = 2
Output: 3
Explanation: T is “ece” which its length is 3.
Example 2:

Input: s = “aa”, k = 1
Output: 2
Explanation: T is “aa” which its length is 2.

Problem URL


Solution

给一个String,找到只能有k个字符组成的最长的子序列的长度。

Approach 1: Sliding window. Maintain a sliding window with size k to get the max length. Using a int array to store the frequency of each character in s. Then j is the fast pointer in the right, I is the slow pointer in the left, count is the number of characters current used. If map do not contain this word, store its frequence and count++; If we have more than k words,

class Solution {
    public int lengthOfLongestSubstringKDistinct(String s, int k) {
        int[] map = new int[256];
        int i = 0, count = 0, res = 0;
        for (int j = 0; j < s.length(); j++){
            if (map[s.charAt(j)]++ == 0){
                count++;
            }
            while (count > k){
                if (--map[s.charAt(i++)] == 0){
                    count--;
                }
            }
            res = Math.max(res, j - i + 1);
        }
        return res;
    }
}

more readable solution

public int lengthOfLongestSubstringKDistinct(String s, int k) {
        int[] bits = new int[256];
        int max = 0, index = 0;
        int count = 0;
        for(int i = 0; i < s.length(); i++) {
            if(bits[s.charAt(i)] == 0) {
                count++;
            }
            bits[s.charAt(i)]++;
            while(count > k) {    // count > k delete char from the substring
                bits[s.charAt(index)]--;
                if(bits[s.charAt(index)] == 0) {
                    count--;
                }
                index++;
            }
            max = Math.max(max, i - index + 1);
        }
        return max;
    }

Time Complexity: O(n)
Space Complexity: O(256)

Approach 2: Using tree map to store the last occurance. But it is slower.

Code
class Solution {
    public int lengthOfLongestSubstringKDistinct(String s, int k) {
        if (s == null || s.isEmpty() || k == 0){
            return 0;
        }
        //lastOccurance stores the last show of index i's character
        TreeMap<Integer, Character> lastOccurance = new TreeMap<>();
        //inWindow stores the char and the index of current window.
        Map<Character, Integer> inWindow = new HashMap<>();
        int i = 0; 
        int res = 1;
        for (int j = 0; j < s.length(); j++){
            char in = s.charAt(j);
            //get new input char and if exceed window size, remove it.
            while (inWindow.size() == k && !inWindow.containsKey(in)){
                int first = lastOccurance.firstKey();
                char out = lastOccurance.get(first);
                inWindow.remove(out);
                lastOccurance.remove(first);
                i = first + 1;
            }
            //update or add new char in two maps.
            if (inWindow.containsKey(in)){
                lastOccurance.remove(inWindow.get(in));
            }
            inWindow.put(in, j);
            lastOccurance.put(j, in);
            res = Math.max(res, j - i + 1);
        }
        return res;
    }
}

Time Complexity: O(nlogk)
Space Complexity: O(k)


Review
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值