LeetCode Daily Challenge-3330. Find the Original Typed String I(Easy)

Anni HuangAnni Huang
5 min read

Problem Understanding

LeetCode 3330: Find the Original Typed String I presents a relatable scenario: Alice accidentally holds keys too long while typing, causing characters to repeat. The key constraint is that she makes this mistake at most once.

Problem Statement

Given a string word representing Alice's final typed output, return the total number of distinct original strings she might have intended to type.

Examples

  • Input: "abbcccc" → Output: 5
    • Possible originals: "abbcccc", "abcccc", "abbccc", "abbcc", "abbc"
  • Input: "abcd" → Output: 1
    • Only one possibility: "abcd" (no repeated characters)
  • Input: "aaaa" → Output: 4
    • Possible originals: "aaaa", "aaa", "aa", "a"

The Python Solution Explained

class Solution:
    def possibleStringCount(self, word: str) -> int:
        # count ocurrence of each character
        # find all the combinations based on the sequence
        # return the number of comb
        res = 1
        counter = {}
        for i,w in enumerate(word):
            if i == 0:
                continue
            elif w == word[i-1]:
                    res += 1
        return res

Step-by-Step Breakdown

1. Initialize the Result

res = 1

We start with res = 1 because the original string itself (without any modifications) is always a valid possibility.

2. Iterate Through the String

for i,w in enumerate(word):
    if i == 0:
        continue

We skip the first character since we need to compare each character with its predecessor.

3. Count Consecutive Duplicates

elif w == word[i-1]:
    res += 1

This is the core logic: whenever we find a character that matches the previous one, we increment our result. Each consecutive duplicate represents one additional possible original string.

Why This Works

The key insight is understanding what "at most one mistake" means:

  • Alice can hold down any key for too long, but only once
  • Each group of consecutive identical characters represents a potential mistake location
  • For each duplicate character, we can choose to "remove" it as the mistake

Example Walkthrough: "abbcccc"

Position: 0 1 2 3 4 5 6
String:   a b b c c c c
          ↑ ↑ ↑ ↑ ↑ ↑ ↑
          - - ✓ - ✓ ✓ ✓
  • Position 0: 'a' - Skip (first character)
  • Position 1: 'b''a' - No increment
  • Position 2: 'b' = 'b' - Increment! (res = 2)
  • Position 3: 'c''b' - No increment
  • Position 4: 'c' = 'c' - Increment! (res = 3)
  • Position 5: 'c' = 'c' - Increment! (res = 4)
  • Position 6: 'c' = 'c' - Increment! (res = 5)

Final result: 5

Algorithm Analysis

Time Complexity

  • O(n) where n is the length of the string
  • Single pass through the string with constant work per character

Space Complexity

  • O(1) constant extra space
  • Only using a few variables regardless of input size

Code Optimization

The provided solution can be cleaned up slightly:

class Solution:
    def possibleStringCount(self, word: str) -> int:
        result = 1

        for i in range(1, len(word)):
            if word[i] == word[i-1]:
                result += 1

        return result

Improvements made:

  1. Removed unused counter variable
  2. Used range(1, len(word)) instead of enumerate with skip logic
  3. Clearer variable naming
  4. Removed unnecessary comments

Alternative Approaches

Using Group Counting

def possibleStringCount(self, word: str) -> int:
    result = 1
    i = 0

    while i < len(word):
        count = 1
        # Count consecutive identical characters
        while i + count < len(word) and word[i + count] == word[i]:
            count += 1

        # Each group of size n contributes (n-1) additional possibilities
        result += count - 1
        i += count

    return result

Using itertools.groupby

from itertools import groupby

def possibleStringCount(self, word: str) -> int:
    result = 1

    for char, group in groupby(word):
        group_size = len(list(group))
        result += group_size - 1

    return result

Key Insights and Patterns

1. Pattern Recognition

  • Consecutive duplicates = potential typing mistakes
  • Each duplicate adds exactly one possibility
  • No need for complex combinatorics

2. Greedy Approach

  • We don't need to track which specific characters were mistakes
  • Simply count all opportunities for mistakes

3. Linear Scan Sufficiency

  • One pass through the string captures all information needed
  • No need for backtracking or dynamic programming

Test Cases and Edge Cases

def test_solution():
    sol = Solution()

    # Basic test cases
    assert sol.possibleStringCount("abbcccc") == 5
    assert sol.possibleStringCount("abcd") == 1
    assert sol.possibleStringCount("aaaa") == 4

    # Edge cases
    assert sol.possibleStringCount("a") == 1        # Single character
    assert sol.possibleStringCount("aa") == 2       # Two identical
    assert sol.possibleStringCount("ab") == 1       # Two different
    assert sol.possibleStringCount("aabbcc") == 4   # Multiple groups

    print("All tests passed!")

Common Pitfalls and Debugging Tips

1. Off-by-One Errors

# Wrong: starting from index 0
for i in range(len(word)):
    if i > 0 and word[i] == word[i-1]:  # Extra condition needed

# Right: starting from index 1
for i in range(1, len(word)):
    if word[i] == word[i-1]:  # Clean and direct

2. Misunderstanding the Problem

  • Wrong interpretation: Count all possible character removals
  • Correct interpretation: Count consecutive duplicate positions

3. Overcomplicating the Solution

  • Unnecessary: Complex data structures, group tracking
  • Sufficient: Simple counter with linear scan

Conclusion

LeetCode 3330 demonstrates that sometimes the most elegant solutions are also the simplest. The problem tests your ability to:

  1. Recognize patterns in string manipulation
  2. Understand constraints ("at most once" is key)
  3. Choose appropriate algorithms (linear scan over complex approaches)

The solution's beauty lies in its simplicity: each consecutive duplicate character represents exactly one additional possibility, leading to a straightforward O(n) algorithm that anyone can understand and implement.

Key takeaway: Before diving into complex algorithms, always check if the problem has a simple pattern-based solution!

0
Subscribe to my newsletter

Read articles from Anni Huang directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Anni Huang
Anni Huang

I am Anni HUANG, a software engineer with 3 years of experience in IDE development and Chatbot.