题目:

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 character 'a'.

分析:

有一个打印机,每次只能打印一种字符,同时打印机可以在任意起始位置打印字符,同时会覆盖掉已有的字符。

利用这个打印机,求出打印所给字符串所需的最少打印次数。

我们先来看最坏情况,也就是一个一个打印,那么例如aabba这个字符串时需要5次的,但是我们可以注意到,字符串最后的a,如果前面同样有a这个字符的话,就可以在前一次打印时,将a打印好了,也就是我们可以先打印aaaaa,然后再打印b将a覆盖掉,也就是aabba这样也就只需要两次。

所以我们可以递归求解此问题,求字符串s所需要的打印次数,我们可以先默认打印次数等于除去最后一个字符的字符串所需的次数+1,也就是认为最后一个字符需要单独打印一次,

print(s(i,j)) = print(s(i,j-1))+1

然后我们遍历前面的字符串中的字符,当有字符和最后一个字符相同时,意味着我们可以考虑在前一次打印时,直接将最后一个字符顺带打印出来,我们记字符索引为k,也就是在打印s(i,k)的一步时把最后一个字符打印出来,那么此时打印次数=print(s(i,k)) + print(s(k+1,j-1)),再去和默认打印的次数比较求最小值即可。每次求得的打印字串需要的次数记录下来,调用时直接返回即可。

程序:

C++

class Solution {
public:
int strangePrinter(string s) {
if(s == "")
return ;
int m = s.size();
times = vector<vector<int>>(m, vector<int>(m, ));
return step(s, , m-);
}
private:
int step(string &s, int i, int j){
if(i > j)
return ;
if(i == j)
return ;
if(times[i][j] > )
return times[i][j];
int res = step(s, i, j-) + ;
for(int k = i; k < j; ++k)
if(s[k] == s[j])
res = min(res, step(s, i, k) + step(s, k+, j-));
times[i][j] = res;
return res;
}
vector<vector<int>> times;
};

Java

class Solution {
public int strangePrinter(String s) {
if(s.length() == 0)
return 0;
int l = s.length();
times = new int[l][l];
return step(s, 0, l-1);
}
private int step(String s, int i, int j){
if(i > j)
return 0;
if(i == j)
return 1;
if(times[i][j] > 0)
return times[i][j];
int res = step(s, i, j-1) + 1;
for(int k = i; k < j; ++k)
if(s.charAt(k) == s.charAt(j))
res = Math.min(res, step(s, i, k) + step(s, k+1, j-1));
times[i][j] = res;
return res;
}
private int[][] times;
}

LeetCode 664. Strange Printer 奇怪的打印机(C++/Java)的更多相关文章

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

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

  2. leetcode 664. Strange Printer

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

  3. 664. Strange Printer

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

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

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

  5. Java实现 LeetCode 664 奇怪的打印机(DFS)

    664. 奇怪的打印机 有台奇怪的打印机有以下两个特殊要求: 打印机每次只能打印同一个字符序列. 每次可以在任意起始和结束位置打印新字符,并且会覆盖掉原来已有的字符. 给定一个只包含小写英文字母的字符 ...

  6. Leetcode 664.奇怪的打印机

    奇怪的打印机 有台奇怪的打印机有以下两个特殊要求: 打印机每次只能打印同一个字符序列. 每次可以在任意起始和结束位置打印新字符,并且会覆盖掉原来已有的字符. 给定一个只包含小写英文字母的字符串,你的任 ...

  7. LeetCode664. Strange Printer

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

  8. HDU 1548 A strange lift 奇怪的电梯(BFS,水)

    题意: 有一座电梯,其中楼层从1-n,每层都有一个数字k,当处于某一层时,只能往上走k层,或者下走k层.楼主在a层,问是否能到达第b层? 思路: 在起点时只能往上走和往下走两个选择,之后的每层都是这样 ...

  9. LeetCode刷题时引发的思考:Java中ArrayList存放的是值还是引用?

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 前言 今天我在刷LeetCode ...

随机推荐

  1. 洛谷P1720 月落乌啼算钱 题解 斐波那契数列/特征方程求解

    题目链接:https://www.luogu.com.cn/problem/P1720 题目描述: 给你一个公式 ,求对应的 \(F_n\) . 解题思路: 首先不难想象这是一个斐波那契数列,我们可以 ...

  2. vmware 14 激活码

    VMware虚拟机已升级至14版本,之前的12版本的秘钥已经无法使用,在此分享一下VMware Workstation 14永久激活密钥: CG54H-D8D0H-H8DHY-C6X7X-N2KG6 ...

  3. 关于Mach-O类型文件那点事

    Mach-O文件简介   Mach-O是一种文件格式,是Mach Object文件格式的缩写. 它通常应用于可执行文件,目标代码,动态库,内核转储等中.   Mach-O作为大部分基于Mach核心的操 ...

  4. Asp.Net Core 3.0 Kestrel服务器下 高性能 WebSocket Server

    最近研究.net core 的各种高性能类型,内存池之类的东西,基于kestrel 服务器的websocket ,写个例子练下手 把原生的Websocket用ArrayPool<T>,Me ...

  5. .NET Core学习笔记(3)——async/await中的Exception处理

    在写了很多年.NET程序之后,年长的猿类在面对异步编程时,仍不时会犯下致命错误,乃至被拖出去杀了祭天.本篇就async/await中的Exception处理进行讨论,为种族的繁衍生息做出贡献……处理a ...

  6. 图解kubernetes服务打散算法的实现源码

    在分布式调度中为了保证服务的高可用和容灾需求,通常都会讲服务在多个区域.机架.节点上平均分布,从而避免单点故障引起的服务不可用,在k8s中自然也实现了该算法即SelectorSpread, 本文就来学 ...

  7. 【Java并发基础】管程简介

    前言 在Java 1.5之前,Java语言提供的唯一并发语言就是管程,Java 1.5之后提供的SDK并发包也是以管程为基础的.除了Java之外,C/C++.C#等高级语言也都是支持管程的. 那么什么 ...

  8. Python赋值没有返回值+笔试

    >>> def test(): i = 1 return i=2 SyntaxError: invalid syntax 原因是python 中赋值语句没有返回值,这里不是C++

  9. 源码详解系列(七) ------ 全面讲解logback的使用和源码

    什么是logback logback 用于日志记录,可以将日志输出到控制台.文件.数据库和邮件等,相比其它所有的日志系统,logback 更快并且更小,包含了许多独特并且有用的特性. logback ...

  10. robotframework,移动端(小程序)自动化,滚动屏幕的方法

    场景描述: 小程序端定位元素有无法定位弹出层内容的问题(自动化工具只能识别到背景主层,无法识别到弹出层) 解决思路: 1.弹出层元素与背景主层元素位置一致,当点击出弹出层时,在定位背景主层即可定位到弹 ...