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. golang 解码未知键的 json 字符串

    我们可以使用 interface 接收 json.Unmarshal 的结果,然后利用 type assertion 特性来进行后续操作. package main import ( "en ...

  2. php中文网在这里给大家汇总了最热门最全面的php面试题

    PHP面试题汇总 视频版: 1.<最新PHP面试视频教程> http://www.php.cn/course/876.html 2.<PHP经典算法面试题> http://ww ...

  3. K8S钩子操作

    简介 我们知道,K8S可以在应用容器启动之前先执行一些预定义的操作,比如事先生成一些数据,以便于应用容器在启动的时候使用.这种方式可以通过init container技术实现,具体可以参考<Ku ...

  4. 3 Kafka两个版本在Zookeeper的元数据存储

    0.8 [consumers, admin, config, controller, brokers, controller_epoch] 这些节点都归于谁管理 consumers: 0.8版本的客户 ...

  5. Linux基础命令【记录】

    后台运行详情:https://www.cnblogs.com/little-ant/p/3952424.html 查看端口.查找等命令 根据关键字查找文件信息: cat <文件名> | g ...

  6. bzoj千题计划147:bzoj1207: [HNOI2004]打鼹鼠

    http://www.lydsy.com/JudgeOnline/problem.php?id=1207 dp[i] 表示打的最后一只鼹鼠是第i只,最多能打多少只鼹鼠 输出max(dp[i]) 错解: ...

  7. springboot中@webfilter注解的filter时注入bean都是null

    在使用@Webfilter注解Filter的情况下,不上外部tomcat时是没有问题的.但是在tomcat下运行时,filter中注入的bean就都是null 解决办法: 一:去掉@Webfilter ...

  8. 一个highcharts混合图Demo

    公司要我做一个highcharts的mockup,其实半个小时就能做完了,我做了将近两个小时,唉!不过还好,总算把东西学会了.勤能补拙! 把代码贴上来 布局很简单,一个div里套两个div,给好id, ...

  9. Composer 自动加载(autoload)机制

    自动加载的类型 总体来说 composer 提供了几种自动加载类型 classmap psr-0 psr-4 files 这几种自动加载都会用到,理论上来说,项目代码用 psr-4 自动加载, hel ...

  10. Python json转字符串的一些细节

    要调PHP那边的接口,php那边一直都校验不过,很是郁闷.没办法,只能让人把发送成功的代码拿过来看,不过是php写的,步骤都是一样: php端: 1. json对象转json字符串. 2. 对json ...