Here’s a rewritten version of the article focusing on the problem-solving aspects:

Mastering Sliding Window: Consecutive Ones and Anagram Indices

This installment, Day 19 of my ongoing daily coding series, delves into two classic sliding window problems: “Max Consecutive Ones III” and “Find All Anagrams in a String.” Both challenges provide excellent opportunities to solidify the fundamental principles of the sliding window technique.

Key Takeaways from Today’s Problems

  • Max Consecutive Ones III: This problem highlights the adaptive nature of the sliding window. The window dynamically expands, and when the condition (more than k zeros) is violated, it contracts from the left. This ensures that we always maintain a valid window while searching for the maximum possible length.
  • Find All Anagrams in a String: For detecting anagrams within a larger string, frequency counters prove to be an efficient tool. By maintaining character counts for both the target pattern and the current window, we can identify anagrams in linear time.
  • Sliding Window Template Reinforcement: Both problems underscore the core sliding window approach: progressively expand the window, conditionally shrink it to maintain validity, and update the result with each valid window.

Deep Dive: #1004 — Max Consecutive Ones III

The goal here is to find the longest subarray containing only 1s, where we’re allowed to flip up to k zeros to ones.

Python Solution

class Solution:
    def longestOnes(self, nums: List[int], k: int) -> int:
        n = len(nums)
        left = 0
        zero_count = 0  # Tracks zeros in the current window
        max_length = 0

        for right in range(n):
            if nums[right] == 0:
                zero_count += 1

            # If current zeros exceed k, shrink window from left
            while zero_count > k:
                if nums[left] == 0:
                    zero_count -= 1
                left += 1

            # Update max_length for the valid window
            max_length = max(max_length, right - left + 1)

        return max_length

C++ Solution

class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int n = nums.size();
        int left = 0;
        int zero_count = 0; // Tracks zeros in the current window
        int max_length = 0;

        for (int right = 0; right < n; ++right) {
            if (nums[right] == 0) {
                zero_count++;
            }

            // If current zeros exceed k, shrink window from left
            while (zero_count > k) {
                if (nums[left] == 0) {
                    zero_count--;
                }
                left++;
            }

            // Update max_length for the valid window
            max_length = max(max_length, right - left + 1);
        }

        return max_length;
    }
};

Complexity Analysis: Both implementations achieve O(n) time complexity as each element is visited at most twice (by left and right pointers). The space complexity is O(1).

Deep Dive: #438 — Find All Anagrams in a String

This problem requires identifying all starting indices of substrings in s that are anagrams of string p.

Python Solution

from collections import Counter

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        n, m = len(s), len(p)
        if m > n:
            return []

        p_freq = Counter(p)
        window_freq = Counter(s[:m])
        result_indices = []

        # Check initial window
        if window_freq == p_freq:
            result_indices.append(0)

        # Slide the window across the rest of the string
        for i in range(m, n):
            # Add new character to window
            window_freq[s[i]] += 1
            # Remove character leaving the window
            left_char = s[i - m]
            window_freq[left_char] -= 1
            if window_freq[left_char] == 0:
                del window_freq[left_char] # Remove if count becomes zero to maintain accurate comparison

            # Check if current window is an anagram
            if window_freq == p_freq:
                result_indices.append(i - m + 1) # Start index of current window

        return result_indices

C++ Solution

#include <vector>
#include <string>
#include <map> // Or array for fixed alphabet size
#include <numeric> // For std::iota if using array

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int n = s.size();
        int m = p.size();
        if (m > n) return {};

        // Use arrays for fixed-size alphabet (a-z) for better performance
        vector<int> p_freq(26, 0);
        vector<int> window_freq(26, 0);

        for (char c : p) {
            p_freq[c - 'a']++;
        }

        vector<int> result_indices;
        int left = 0;

        for (int right = 0; right < n; ++right) {
            window_freq[s[right] - 'a']++; // Expand window

            // When window size matches p's length
            if (right - left + 1 == m) {
                if (window_freq == p_freq) { // Compare frequencies
                    result_indices.push_back(left);
                }
                window_freq[s[left] - 'a']--; // Shrink window
                left++;
            }
        }
        return result_indices;
    }
};

Complexity Analysis: Both solutions run in O(n) time. The space complexity is O(1) (specifically O(26) for the alphabet frequency counters), as the size of the frequency map/array is constant regardless of input string length.

Concluding Achievements

Today’s session successfully demonstrated the versatility of the sliding window paradigm:

  • Max Consecutive Ones III: Effectively implemented the expansion and conditional shrinking of the window to count zeros and maximize the length of consecutive ones.
  • Find All Anagrams in a String: Utilized frequency matching (using Counter in Python and arrays in C++) to precisely locate all anagram starting indices.

This systematic approach reinforces core data structure and algorithm concepts, leading to efficient and robust solutions.

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.
You need to agree with the terms to proceed