Advertisement

String Compression II - LeetCode 1531 Solution

String Compression II - Complete Solution Guide

String Compression II is LeetCode problem 1531, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

Run-length encoding is a string compression method that works by replacing consecutive identical characters (repeated 2 or more times) with the concatenation of the character and the number marking the count of the characters (length of the run). For example, to compress the string "aabccc" we replace "aa" by "a2" and replace "ccc" by "c3" . Thus the compressed string becomes "a2bc3" . Notice that in this problem, we are not adding '1' after single characters. Given a string s and an integer k .

Detailed Explanation

The problem asks us to compress a given string 's' using run-length encoding, but with the added ability to delete at most 'k' characters from the string before compression. The goal is to find the minimum length of the run-length encoded string after performing the optimal deletions. Run-length encoding replaces consecutive identical characters with the character and the count of repetitions (if the count is greater than 1). For example, 'aaabcccd' becomes 'a3bc3d'. We need to determine which characters to delete to minimize the final encoded string's length.

Solution Approach

The solution employs a top-down dynamic programming approach with memoization. A recursive function `solve(start, k_rem)` is defined, where `start` is the starting index of the substring being considered, and `k_rem` is the number of characters that can still be deleted. The function returns the minimum length of the run-length encoded string for the substring starting at `start` after deleting at most `k_rem` characters. The function explores two options for each character: delete it or keep it. If the character is kept, it iterates through the remaining string, forming a run and calculating the cost of encoding that run. The minimum cost among all possible runs is then returned.

Step-by-Step Algorithm

  1. Step 1: Define a recursive function `solve(start, k_rem)` to calculate the minimum length of the compressed string starting from index `start` with `k_rem` deletions remaining.
  2. Step 2: Base Cases: If `k_rem` becomes negative, return infinity (or a large value) as it's an invalid state. If `start + k_rem` is greater than or equal to the length of the string 'n', it means all remaining characters can be deleted, so return 0.
  3. Step 3: Memoization: Check if the result for the current state (start, k_rem) is already cached. If so, return the cached value.
  4. Step 4: Option 1: Delete the character at index `start`. Recursively call `solve(start + 1, k_rem - 1)` and store the result.
  5. Step 5: Option 2: Keep the character at index `start` and form a run. Iterate from `start` to the end of the string, counting the number of identical characters (count) and the number of different characters (deletions).
  6. Step 6: If the number of deletions exceeds `k_rem`, break the inner loop.
  7. Step 7: Calculate the cost of encoding the current run. The cost is 1 if count is 1, 2 if count is between 2 and 9, 3 if count is between 10 and 99, and 4 if count is 100.
  8. Step 8: Recursively call `solve(j + 1, k_rem - deletions)` and add the cost of the current run to the result. Update the minimum result.
  9. Step 9: Store the minimum result in the cache and return it.

Key Insights

  • Insight 1: Dynamic programming is crucial because we need to explore different combinations of character deletions and keep track of the minimum compressed length.
  • Insight 2: The core idea is to consider two options for each character: either delete it or keep it and form a run.
  • Insight 3: Memoization or caching is necessary to avoid redundant calculations, as the same subproblems will be encountered multiple times due to overlapping subproblems.
  • Insight 4: Carefully track the number of deletions available and the length of the run that is being formed to make the decision on whether to delete or keep the current character.

Complexity Analysis

Time Complexity: O(n^2*k)

Space Complexity: O(n*k)

Topics

This problem involves: String, Dynamic Programming.

Companies

Asked at: Toptal.