Problem
There is a strange printer with the following two special properties:
The printer can only print a sequence of the same character each time.
At each turn, the printer can print new characters starting from and ending at any place and will cover the original existing characters.
Given a string s
, return the minimum number of turns the printer needed to print it.
Example 1:
Input: s = "aaabbb"
Output: 2
Explanation: Print "aaa" first and then print "bbb".
Example 2:
Input: s = "aba"
Output: 2
Explanation: Print "aaa" first and then print "b" from the second place of the string, which will cover the existing character 'a'.
Constraints:
1 <= s.length <= 100
s
consists of lowercase English letters.
Solution (Java)
class Solution {
public int strangePrinter(String s) {
if (s.length() == 0) {
return 0;
}
int[][] dp = new int[s.length()][s.length()];
for (int i = s.length() - 1; i >= 0; i--) {
for (int j = i; j < s.length(); j++) {
if (i == j) {
dp[i][j] = 1;
} else if (s.charAt(i) == s.charAt(i + 1)) {
dp[i][j] = dp[i + 1][j];
} else {
dp[i][j] = dp[i + 1][j] + 1;
for (int k = i + 1; k <= j; k++) {
if (s.charAt(k) == s.charAt(i)) {
dp[i][j] = Math.min(dp[i][j], dp[i + 1][k - 1] + dp[k][j]);
}
}
}
}
}
return dp[0][s.length() - 1];
}
}
Solution (C++)
class Solution {
public:
int strangePrinter(const string& s) {
int l = s.length();
t_ = vector<vector<int>>(l, vector<int>(l, 0));
return turn(s, 0, s.length() - 1);
}
private:
// Minimal turns to print s[i] to s[j]
int turn(const string& s, int i, int j) {
// Empty string
if (i > j) return 0;
// Solved
if (t_[i][j] > 0) return t_[i][j];
// Default behavior, print s[i] to s[j-1] and print s[j]
int ans = turn(s, i, j-1) + 1;
for (int k = i; k < j; ++k)
if (s[k] == s[j])
ans = min(ans, turn(s, i, k) + turn(s, k + 1, j - 1));
return t_[i][j] = ans;
}
vector<vector<int>> t_;
};
Explain:
nope.
Complexity:
- Time complexity : O(n).
- Space complexity : O(n).