zoukankan      html  css  js  c++  java
  • (leetcode每日打卡)秋叶收藏集【动态规划】

    LCP 19.秋叶收藏集

    题目链接

    算法

    动态规划

    时间复杂度O(n)

    1.题目要求最终形成[红、黄、红]三部分,每部分数量可以不相等,问最终调整操作数量最小是多少。这道题一开始考虑暴力去做,枚举两个分界点,即红黄,黄红之间的分界点的位置,但由于长度是1e5,时间复杂度为O(n^2)级别,故此法作废。

    2.通过查看官方题解,了解到这道题可以使用动态规划去做,可以将时间复杂度优化到O(n)级别,为方便查阅复习,现结合自己的理解写下该题解。具体如下:

    可以定义一个数组f[i][j],表示符合要求的最小的操作数,即使leaves[]数组从0到i的值符合题目规范的最小的操作数。i的范围是[0,leaves.length),j的范围是[0,2],其中0表示当前叶子为红色(在黄色前面),1表示当前叶子为黄色,2表示当前叶子为红色(在黄色后面)。

    初始时f[0][0]的值会由第一片叶子的颜色决定。下面分情况讨论j的不同值的情况:

    (1)当j=0时,f[i][0] = f[i-1][0] + isYellow(i)。isYellow函数会根据叶子的颜色返回对应的布尔值;同时需注意j=0这种情况下i最大为leaves.length-3,因为题目要求每部分叶子数量至少为1个;

    (2)当j=1时,f[i][1] = min(f[i-1][0],f[i-1][1]) + isRed(i) 。该叶子左面的叶子的颜色可能是红色,也可能是黄色,取形成前面两种情况操作的最小值即可。同时需要判断当前叶子是否黄色。在这种情况下i最大值为leaves.length-2,最小值为1;

    (3)当j=2时,f[i][2] = min(f[i-1][1],f[i-1][2]) + isYellow(i);。该叶子左面的叶子的颜色可能是红色,也可能是黄色,取形成前面两种情况操作的最小值即可。同时需要判断当前叶子是否为红色。在这种情况下i最大值为leaves.length-1,最小值为2;

    最终返回结果为f[leaves.length - 1]

    C++代码

    //一开始是用函数调用的,但超时,故直接判断
    class Solution {   
    public:
    /*
        bool isYellow(string leaves, int u){
            return (leaves[u] == 'y');
        }
        bool isRed(string leaves, int u){
            return (leaves[u] == 'r');
        }
    */
        int minimumOperations(string leaves) {
            int len = leaves.length();
            vector<vector<int> > f(len, vector<int>(3, INT_MAX));
            //f[0][0] = isYellow(leaves, 0);
            f[0][0] = (leaves[0] == 'y');
            for(int i = 1; i < len; i++){
                int yellow = (leaves[i] == 'y');
                int red = (leaves[i] == 'r');
                if(i < len - 2){
                    //f[i][0] = f[i-1][0] + (int)isYellow(leaves, i);
                    f[i][0] = f[i-1][0] + yellow;
                }
                if(i >= 1 && i < len - 1){
                    //f[i][1] = min(f[i-1][0],f[i-1][1]) + (int)isRed(leaves, i);
                    f[i][1] = min(f[i-1][0],f[i-1][1]) + red;
                }
                if(i >= 2){
                    //f[i][2] = min(f[i-1][1],f[i-1][2]) + (int)isYellow(leaves, i);
                    f[i][2] = min(f[i-1][1],f[i-1][2]) + yellow;
                }
            }
            return f[len - 1][2];
        }
    };
    
  • 相关阅读:
    Java实现 洛谷 P1060 开心的金明
    (Java实现) 洛谷 P1605 迷宫
    (Java实现) 洛谷 P1605 迷宫
    (Java实现)洛谷 P1093 奖学金
    (Java实现)洛谷 P1093 奖学金
    Java实现 洛谷 P1064 金明的预算方案
    Java实现 洛谷 P1064 金明的预算方案
    (Java实现) 洛谷 P1031 均分纸牌
    QT树莓派交叉编译环开发环境搭建(附多个exe工具下载链接)
    武则天红人对唐睿宗的桃色报复(如此缺少城府,注定了要在宫廷中过早地出局)
  • 原文地址:https://www.cnblogs.com/KeepZ/p/13759475.html
Copyright © 2011-2022 走看看