There is a strange printer with the following two special requirements:

  1. The printer can only print a sequence of the same character each time.
  2. At each turn, the printer can print new characters starting from and ending at any places, and will cover the original existing characters.

Given a string consists of lower English letters only, your job is to count the minimum number of turns the printer needed in order to print it.

Example 1:

Input: "aaabbb"
Output: 2
Explanation: Print "aaa" first and then print "bbb".

Example 2:

Input: "aba"
Output: 2
Explanation: Print "aaa" first and then print "b" from the second place of the string, which will cover the existing c

分析

这类题目的本质是寻找做某件事在没有特定步骤的情形下总共有多少种实现方法,可以通过遍历所有可能来解决,是一个典型的dp问题。

dp[i][j] 代表变成string中从index i 到 index j 部分需要的最少print次数。 那么有:

  • dp[i][i] = 1: we need 1 turn to paint a single character.
  • dp[i][i + 1]
    • dp[i][i + 1] = 1 if s.chartAt(i) == s.charAt(i + 1)  
    • dp[i][i + 1] = 2 if s.chartAt(i) != s.charAt(i + 1)

Then we can iteration len from 2 to possibly n. For each iteration, we iteration start index from 0 to the farthest possible.

  • The maximum turns for dp[start][start + len] is len + 1, i.e. print one character each time.
  • We can further divide the substring to two parts: start -> start+k and start+k+1 -> start+len. It is something as following:
    index |start  ...  start + k| |start + k + 1 ... start + len|
    char | a ... b | | c ... b |
    • As shown above, if we have s.charAt(start + k) == s.charAt(start + len), we can make it in one turn when we print this character (i.e. b here)
    • This case we can reduce our turns to dp[start][start + k] + dp[start + k + 1][start + len] - 1

难理解的部分来了,首选对于 dp[start][start+len] 的最大值肯定是len+1, 也就是每次只print一个字符。

需要注意的几点是:1. 每次打印一个字符或者是相同字符的序列,这可以推出如果一个字符串里出现了一个不同的字符,那么至少要为这个字符打印一次。

         2. 因为每次的打印可以选择任何位置,可以覆盖原有字符

         3. 这是个从无到有,然后再去替换的过程

可以将substring分成两部分,start -> start+k and start+k+1 -> start+len,以索引k作为分割,如果 start+k 处的字符和 start+len初的字符相同,那当我们在前面打印这个字符b时可以选择一次性打印连续个b,这样在对于dp[start + k + 1][start + len]来说相当于减少了一次打印b的过程,所以 dp[start][start+len] 就被分解成了子问题 dp[start][start + k] + dp[start + k + 1][start + len] - 1。

代码

class Solution {
public int strangePrinter(String s) {
if (s == null || s.length() == 0) {
return 0;
} int n = s.length();
int[][] dp = new int[n][n];
for (int i = 0; i < n; i++) {
dp[i][i] = 1;
if (i < n - 1) {
dp[i][i + 1] = s.charAt(i) == s.charAt(i + 1) ? 1 : 2;
}
} for (int len = 2; len < n; len++) {
for (int start = 0; start + len < n; start++) {
dp[start][start + len] = len + 1;
for (int k = 0; k < len; k++) {
int temp = dp[start][start + k] + dp[start + k + 1][start + len];
dp[start][start + len] = Math.min(
dp[start][start + len],
s.charAt(start + k) == s.charAt(start + len) ? temp - 1 : temp
);
}
}
} return dp[0][n - 1];
}
}

LeetCode664. Strange Printer的更多相关文章

  1. [Swift]LeetCode664. 奇怪的打印机 | Strange Printer

    There is a strange printer with the following two special requirements: The printer can only print a ...

  2. [LeetCode] Strange Printer 奇怪的打印机

    There is a strange printer with the following two special requirements: The printer can only print a ...

  3. leetcode 664. Strange Printer

    There is a strange printer with the following two special requirements: The printer can only print a ...

  4. LeetCode 664. Strange Printer 奇怪的打印机(C++/Java)

    题目: There is a strange printer with the following two special requirements: The printer can only pri ...

  5. 664. Strange Printer

    class Solution { public: int dp[100][100]; int dfs(const string &s, int i,int j) { if(i>j)ret ...

  6. [LeetCode] Burst Balloons 打气球游戏

    Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...

  7. [LeetCode] Remove Boxes 移除盒子

    Given several boxes with different colors represented by different positive numbers. You may experie ...

  8. [LeetCode] Zuma Game 祖玛游戏

    Think about Zuma Game. You have a row of balls on the table, colored red(R), yellow(Y), blue(B), gre ...

  9. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

随机推荐

  1. STL中的优先级队列priority_queue

    priority_queue(queue类似)完全以底部容器为根据,再加上二叉堆(大根堆或者小根堆)的实现原理,所以其实现非常简单,缺省情况下priority_queue以vector作为底部容器.另 ...

  2. noVNC连接CentOS,以Web方式交付VNC远程连接

    什么是noVNC? noVNC 是一个 HTML5 VNC 客户端,采用 HTML 5 WebSockets, Canvas 和 JavaScript 实现,noVNC 被普遍用在各大云计算.虚拟机控 ...

  3. HashMap源码分析-基于JDK1.8

    hashMap数据结构 类注释 HashMap的几个重要的字段 hash和tableSizeFor方法 HashMap的数据结构 由上图可知,HashMap的基本数据结构是数组和单向链表或红黑树. 以 ...

  4. bzoj千题计划109:bzoj1019: [SHOI2008]汉诺塔

    http://www.lydsy.com/JudgeOnline/problem.php?id=1019 题目中问步骤数,没说最少 可以大胆猜测移动方案唯一 (真的是唯一但不会证) 设f[i][j] ...

  5. 翻译: 星球生成 II

    翻译: 星球生成 II 本文翻译自Planet Generation - Part II 译者: FreeBlues 以下为译文: 概述 在前一章 我解释了如何为星球创建一个几何球体. 在本文中, 我 ...

  6. java 数字转换成字符串

    一.各种数字类型转换成字符串型:  public static void main(String[] args) { double value = 123456.123; String str = S ...

  7. What Does “Neurons that Fire Together Wire Together” Mean?

    What Does “Neurons that Fire Together Wire Together” Mean? I’ve heard the phrase “neurons that fire ...

  8. JAVA编程之——反射Reflect

    说到反射,首先要说一下Java中的类和对象. 在Java中万事万物皆对象(有两个 例外,一个是普通数据类型,另一个是静态的东西,静态的东西不是对象的,是属于类的). 在Java中,类也是对象,类是ja ...

  9. pywinauto: 导入时遇到 "TypeError: LoadLibrary() argument 1 must be string, not unicode"

    pywinauto: 导入时遇到 "TypeError: LoadLibrary() argument 1 must be string, not unicode" 经查询, 看到 ...

  10. [转] malloc基本实现

    任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...