Program to partition two strings such that each partition forms anagram in Python

Suppose we have two non-empty strings s and t that are of the same length. We have to partition them into substrings such that each pair of s and t substring is the same size and they are anagrams of each other. Now find the cut indexes such that it results in the maximum number of cuts of s and t. If no result is found, then return empty list.

So, if the input is like s = "bowcattiger" t = "owbactietgr", then the output will be [0, 3, 5, 6, 10], as we can partition the string into 5 partitions such that each string is an anagram of each other. s = ["bow", "ca", "t", "tige", "r"], t = ["owb", "ac", "t", "ietg", "r"]

Algorithm Steps

To solve this, we will follow these steps ?

  • intervals := a new list
  • cs := a map with character present in s and its frequency
  • ct := a map with character present in t and its frequency
  • if cs is not same as ct, then
    • return a new list
  • for x in range size of s - 1 down to 0, do
    • cs[s[x]] := cs[s[x]] - 1
    • ct[t[x]] := ct[t[x]] - 1
    • if cs is same as ct, then
      • insert x at the end of intervals
  • sort the list intervals and return

Example Implementation

Let us see the following implementation to get better understanding ?

from collections import Counter

class Solution:
    def solve(self, a, b):
        intervals = []
        ca = Counter(a)
        cb = Counter(b)
        if ca != cb:
            return []
        for x in reversed(range(len(a))):
            ca[a[x]] -= 1
            cb[b[x]] -= 1
            if ca == cb:
                intervals.append(x)
        return sorted(intervals)

ob = Solution()
s = "bowcattiger"
t = "owbactietgr"
print(ob.solve(s, t))
[0, 3, 5, 6, 10]

How It Works

The algorithm uses character frequency counting to determine valid partition points. It starts by checking if both strings have the same character frequencies overall. Then, it iterates backwards through the strings, decrementing character counts and checking when the remaining portions have identical frequency distributions. Each such point represents a valid cut position where the consumed prefixes form anagrams.

Step-by-Step Execution

For the example strings "bowcattiger" and "owbactietgr" ?

from collections import Counter

s = "bowcattiger"
t = "owbactietgr"

# Initial character counts
print("Initial counts:")
print("s:", Counter(s))
print("t:", Counter(t))

# Simulate the algorithm
ca = Counter(s)
cb = Counter(t)
intervals = []

for i, x in enumerate(reversed(range(len(s)))):
    ca[s[x]] -= 1
    cb[t[x]] -= 1
    print(f"Step {i+1}: After removing s[{x}]='{s[x]}', t[{x}]='{t[x]}'")
    print(f"  Remaining counts equal? {ca == cb}")
    if ca == cb:
        intervals.append(x)
        print(f"  Added cut point: {x}")

print(f"Final result: {sorted(intervals)}")
Initial counts:
s: Counter({'t': 2, 'g': 2, 'b': 1, 'o': 1, 'w': 1, 'c': 1, 'a': 1, 'i': 1, 'e': 1, 'r': 1})
t: Counter({'t': 2, 'g': 2, 'o': 1, 'w': 1, 'b': 1, 'a': 1, 'c': 1, 'i': 1, 'e': 1, 'r': 1})
Step 1: After removing s[10]='r', t[10]='r'
  Remaining counts equal? True
  Added cut point: 10
Step 2: After removing s[9]='e', t[9]='g'
  Remaining counts equal? False
Step 3: After removing s[8]='g', t[8]='t'
  Remaining counts equal? False
Step 4: After removing s[7]='i', t[7]='e'
  Remaining counts equal? False
Step 5: After removing s[6]='t', t[6]='t'
  Remaining counts equal? True
  Added cut point: 6
Step 6: After removing s[5]='t', t[5]='i'
  Remaining counts equal? True
  Added cut point: 5
Step 7: After removing s[4]='a', t[4]='c'
  Remaining counts equal? False
Step 8: After removing s[3]='c', t[3]='a'
  Remaining counts equal? True
  Added cut point: 3
Step 9: After removing s[2]='w', t[2]='b'
  Remaining counts equal? False
Step 10: After removing s[1]='o', t[1]='w'
  Remaining counts equal? False
Step 11: After removing s[0]='b', t[0]='o'
  Remaining counts equal? True
  Added cut point: 0
Final result: [0, 3, 5, 6, 10]

Conclusion

This algorithm efficiently finds the maximum number of anagram partitions by using character frequency counting and working backwards through the strings. The time complexity is O(n) where n is the length of the strings, making it an optimal solution for this partitioning problem.

Updated on: 2026-03-25T10:44:14+05:30

616 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements