algoadvance

Leetcode 3146. Permutation Difference between Two Strings

Problem Statement

You are given two strings s1 and s2 of equal length. Selecting a substring from each string, check if there exists a permutation of the substring of s1 that matches with the substring of s2. Write a function that returns true if such a permutation exists, otherwise return false.

Clarifying Questions

  1. Are the two substrings always of the same length?
    • Yes, the substring from s1 and s2 should be of the same length.
  2. Can the strings s1 and s2 contain special characters or numbers?
    • The problem doesn’t restrict characters, so assume the strings can be comprised of any characters.
  3. Do the substrings need to be contiguous?
    • Yes, the substrings are contiguous parts of the strings s1 and s2.
  4. Should the function be case-sensitive, meaning ‘A’ and ‘a’ are considered different?
    • Yes, consider the function case-sensitive unless specified otherwise.

Strategy

  1. Use a sliding window approach combined with a character frequency count to avoid having to recompute frequency counts for overlapping parts of the strings.
  2. Initialize frequency counts for the first window in both s1 and s2.
  3. Slide the window across the strings and update the counts, checking after each slide if the two frequency counts match.

Time Complexity

The time complexity should be O(n*26) (effectively O(n) since 26 is a constant) where n is the length of the strings, because we’re processing each character once and updating/counting frequencies in constant time.

Code

Here is the C++ solution for the given problem:

#include <iostream>
#include <vector>
#include <string>

bool checkEqualCounts(const std::vector<int>& count1, const std::vector<int>& count2) {
    for (int i = 0; i < 26; ++i) {
        if (count1[i] != count2[i]) {
            return false;
        }
    }
    return true;
}

bool findPermutationSubstring(const std::string& s1, const std::string& s2) {
    int n = s1.length();
    if (n != s2.length()) return false;
    
    std::vector<int> s1Count(26, 0);
    std::vector<int> s2Count(26, 0);
    
    // Initialize the counts for the first window
    for (int i = 0; i < n; ++i) {
        s1Count[s1[i] - 'a']++;
        s2Count[s2[i] - 'a']++;
    }
    
    for (int i = 0; i <= n; ++i) {
        if (checkEqualCounts(s1Count, s2Count)) return true;

        if (i < n) {
            s2Count[s2[i] - 'a']--;
            s2Count[s2[i + n - 1] - 'a']++;
        }
    }
    
    return false;
}

int main() {
    std::string s1 = "abc";
    std::string s2 = "bca";
    bool result = findPermutationSubstring(s1, s2);
    std::cout << (result ? "true" : "false") << std::endl;

    return 0;
}

In this solution, we slide a window over s2 and update the frequency counts in O(1) time, checking if the frequency counts of the two windows match to determine if a permutation exists.

Cut your prep time in half and DOMINATE your interview with AlgoAdvance AI