Longest Substring with At Most Two Distinct Characters

Problem

Find the longest continuous part of the word that contains at most two different characters. Print its length.

Constraints

  • 1 <= length <= 10^5
  • lowercase letters

Examples

Input

eceba

Output

3

Solutions

Best approachTime O(n)Space O(1)

The window grows on the right. When it holds a third different character, the left side moves until only two remain. Each character enters and leaves once, so it is O(n).

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Longest part with two characters.
 * Input   : One word.
 * Output  : The length.
 * Approach: Sliding window.
 * Time    : O(n)
 * Space   : O(1)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static int solve(String s) {
        // Step 1: The window is s[left..right]. "counts" says how many times each character is inside the window.
        java.util.Map<Character, Integer> counts = new java.util.HashMap<Character, Integer>();
        int left = 0;
        int best = 0;
        for (int right = 0; right < s.length(); right++) {
            counts.merge(s.charAt(right), 1, Integer::sum);
            // Step 2: Too many different characters: move the left side until only two are left.
            while (counts.size() > 2) {
                char out = s.charAt(left++);
                if (counts.merge(out, -1, Integer::sum) == 0) {
                    counts.remove(out);
                }
            }
            best = Math.max(best, right - left + 1);
        }
        return best;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.hasNextLine() ? scanner.nextLine() : "";
        System.out.println(solve(s));
    }
}
Hints (2)
  1. When do we move the left side?
  2. Why remove a key at count 0?