Welcome to Subscribe On Youtube
2430. Maximum Deletions on a String
Description
You are given a string s
consisting of only lowercase English letters. In one operation, you can:
- Delete the entire string
s
, or - Delete the first
i
letters ofs
if the firsti
letters ofs
are equal to the followingi
letters ins
, for anyi
in the range1 <= i <= s.length / 2
.
For example, if s = "ababc"
, then in one operation, you could delete the first two letters of s
to get "abc"
, since the first two letters of s
and the following two letters of s
are both equal to "ab"
.
Return the maximum number of operations needed to delete all of s
.
Example 1:
Input: s = "abcabcdabc" Output: 2 Explanation: - Delete the first 3 letters ("abc") since the next 3 letters are equal. Now, s = "abcdabc". - Delete all the letters. We used 2 operations so return 2. It can be proven that 2 is the maximum number of operations needed. Note that in the second operation we cannot delete "abc" again because the next occurrence of "abc" does not happen in the next 3 letters.
Example 2:
Input: s = "aaabaab" Output: 4 Explanation: - Delete the first letter ("a") since the next letter is equal. Now, s = "aabaab". - Delete the first 3 letters ("aab") since the next 3 letters are equal. Now, s = "aab". - Delete the first letter ("a") since the next letter is equal. Now, s = "ab". - Delete all the letters. We used 4 operations so return 4. It can be proven that 4 is the maximum number of operations needed.
Example 3:
Input: s = "aaaaa" Output: 5 Explanation: In each operation, we can delete the first letter of s.
Constraints:
1 <= s.length <= 4000
s
consists only of lowercase English letters.
Solutions
Solution 1: Memoization Search
We design a function
The calculation process of the function
- If
, theni≥n , return directly.dfs(i)=0 - Otherwise, we enumerate the length of the string
, wherej . If1≤j≤(n−1)/2 , we can deletes[i..i+j]=s[i+j..i+j+j] , thens[i..i+j] . We need to enumerate alldfs(i)=max(dfs(i),dfs(i+j)+1) to find the maximum value ofj .dfs(i)
Here we need to quickly determine whether
To avoid repeated calculations, we can use memoization search and use an array
The time complexity is
Solution 2: Dynamic Programming
We can change the memoization search in Solution 1 to dynamic programming. Define
We can enumerate
The time complexity is
-
class Solution { private int n; private Integer[] f; private int[][] g; public int deleteString(String s) { n = s.length(); f = new Integer[n]; g = new int[n + 1][n + 1]; for (int i = n - 1; i >= 0; --i) { for (int j = i + 1; j < n; ++j) { if (s.charAt(i) == s.charAt(j)) { g[i][j] = g[i + 1][j + 1] + 1; } } } return dfs(0); } private int dfs(int i) { if (i == n) { return 0; } if (f[i] != null) { return f[i]; } f[i] = 1; for (int j = 1; j <= (n - i) / 2; ++j) { if (g[i][i + j] >= j) { f[i] = Math.max(f[i], 1 + dfs(i + j)); } } return f[i]; } }
-
class Solution { public: int deleteString(string s) { int n = s.size(); int g[n + 1][n + 1]; memset(g, 0, sizeof(g)); for (int i = n - 1; ~i; --i) { for (int j = i + 1; j < n; ++j) { if (s[i] == s[j]) { g[i][j] = g[i + 1][j + 1] + 1; } } } int f[n]; memset(f, 0, sizeof(f)); function<int(int)> dfs = [&](int i) -> int { if (i == n) { return 0; } if (f[i]) { return f[i]; } f[i] = 1; for (int j = 1; j <= (n - i) / 2; ++j) { if (g[i][i + j] >= j) { f[i] = max(f[i], 1 + dfs(i + j)); } } return f[i]; }; return dfs(0); } };
-
class Solution: def deleteString(self, s: str) -> int: @cache def dfs(i: int) -> int: if i == n: return 0 ans = 1 for j in range(1, (n - i) // 2 + 1): if s[i : i + j] == s[i + j : i + j + j]: ans = max(ans, 1 + dfs(i + j)) return ans n = len(s) return dfs(0)
-
func deleteString(s string) int { n := len(s) g := make([][]int, n+1) for i := range g { g[i] = make([]int, n+1) } for i := n - 1; i >= 0; i-- { for j := i + 1; j < n; j++ { if s[i] == s[j] { g[i][j] = g[i+1][j+1] + 1 } } } f := make([]int, n) var dfs func(int) int dfs = func(i int) int { if i == n { return 0 } if f[i] > 0 { return f[i] } f[i] = 1 for j := 1; j <= (n-i)/2; j++ { if g[i][i+j] >= j { f[i] = max(f[i], dfs(i+j)+1) } } return f[i] } return dfs(0) }
-
function deleteString(s: string): number { const n = s.length; const f: number[] = new Array(n).fill(0); const dfs = (i: number): number => { if (i == n) { return 0; } if (f[i] > 0) { return f[i]; } f[i] = 1; for (let j = 1; j <= (n - i) >> 1; ++j) { if (s.slice(i, i + j) == s.slice(i + j, i + j + j)) { f[i] = Math.max(f[i], dfs(i + j) + 1); } } return f[i]; }; return dfs(0); }