zoukankan      html  css  js  c++  java
  • LeetCode 664. Strange Printer 奇怪的打印机(C++/Java)

    题目:

    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 0;
            int m = s.size();
            times = vector<vector<int>>(m, vector<int>(m, 0));
            return step(s, 0, m-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[k] == s[j])
                    res = min(res, step(s, i, k) + step(s, k+1, j-1));
            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;
    }
  • 相关阅读:
    03-数据库必会问题
    2017.06.29数据挖掘基础概念第二.三章
    2017.06.29 数据挖掘概念知识第一章
    2017.06.9 金融时间序列分析之Eview使用基础
    2017.05.27 WeX5后端服务开发之注册
    2017.5.24 Git使用说明初级
    2017.05.06FreeCodeCamp编程之JS面向对象编程学习
    2017.05.05FreeCodeCamp前端编程之Javascript实现laohuji
    2017.05.05 freecodecamp前端编程之正则表达式
    2017.5.2 Javascript练习之FreecodeCamp--21点算法
  • 原文地址:https://www.cnblogs.com/silentteller/p/12304857.html
Copyright © 2011-2022 走看看