• b_lc_秋叶收集器(分类讨论dp+滚动数组优化)


    出于美观整齐的考虑,小扣想要将收藏集中树叶的排列调整成「红、黄、红」三部分。每部分树叶数量可以不相等,但均需大于等于 1。每次调整操作,小扣可以将一片红叶替换成黄叶或者将一片黄叶替换成红叶。请问小扣最少需要多少次调整操作才能将秋叶收藏集调整完毕。

    输入:leaves = "rrryyyrryyyrr"
    输出:2
    解释:调整两次,将中间的两片红叶替换成黄叶,得到 "rrryyyyyyyyrr"
    提示:3 <= leaves.length <= 10^5
    

    方法一:dp

    目标是将 s 变成 rrr...yyy...rrr...{红...黄...红...}

    • 定义状态
      • f[i][0] 表示序列 0..i 都是r
      • f[i][1] 表示序列 0..i 从r变成了y,且y结尾
      • f[i][2] 表示序列 0..i 从r变成了y,又从y变成了r,且r结尾
    • 思考初始化:
      • f[0][0]=s[0]==r ? 0 : 1
      • f[0][1]=+inf
      • f[0][2]=+inf
    • 思考状态转移方程
      • if (s[i]='r') 时,r 可以修改成 y,也可不修改
        • f[i][0]=f[i-1][0]
        • f[i][1]=min(f[i-1][0]+1, f[i-1][1]+1)
        • f[i][2]=min(f[i-1][2], f[i-1][1]),当前就是以 r 结尾,所以只需取到前一个状态即可
      • if (s[i]='y') 时,y 可以修改成 r,也可不修改
        • f[i][0]=f[i-1][0]+1
        • f[i][1]=min(f[i-1][1], f[i-1][0]),当前就是以 y 结尾,所以只需取 f[i-1][1]/f[i-1][0],这里没有 f[i-1][2] 的事,因为需要渐变
        • f[i][2]=min(f[i-1][1]+1, f[i-1][2]+1),
    • 思考输出:f[n-1][2]
    class Solution {
    public:
        // rrr...yyy...rrr
        int minimumOperations(string s) {
            if (s.empty()) return 0;
            int n=s.size(), inf=0x3f3f3f3f, f[n+1][3]; 
            memset(f, inf, sizeof f); f[0][0]=0;
            if (s[0]=='y') f[0][0]=1;
            
            for (int i=1; i<n; i++) {
                if (s[i]=='r') {
                    f[i][0]=f[i-1][0];
                    f[i][1]=min(f[i-1][0], f[i-1][1])+1;
                    f[i][2]=min(f[i-1][1], f[i-1][2]);
                } else {
                    f[i][0]=f[i-1][0]+1;
                    f[i][1]=min(f[i-1][1], f[i-1][0]);
                    f[i][2]=min(f[i-1][1], f[i-1][2])+1;
                }
            }
            return f[n-1][2];
        }
    };
    

    复杂度分析

    • Time\(O(n)\)
    • Space\(O(n)\)

    参考别人的滚动数组优化解法,相比自己写的,orz...

  • 相关阅读:
    RxJava Android(RxAndroid) 开发全家桶
    Android Retrofit RxJava实现缓存
    Android Touch事件传递机制详解 下
    Android Touch事件传递机制详解 上
    Android Framework 记录之二
    XMind 8 Update 7 Pro 激活码
    leetcode 2-> Add Two Numbers
    leetcode 1 -> Two Sum
    leetcode 3-> Longest Substring Without Repeating Characters
    Python enumerate() 函数
  • 原文地址:https://www.cnblogs.com/wdt1/p/13663357.html
Copyright © 2020-2023  润新知