美文网首页动态规划
Java 算法 - 数字翻转(动态规划)

Java 算法 - 数字翻转(动态规划)

作者: 琼珶和予 | 来源:发表于2018-03-12 01:19 被阅读126次

    题意

    给你一个01构成的数组。请你找出最小翻转步数,使得数组满足以下规则:
    1的后面可以是1或者0,但是0的后面必须是0。
    

    样例

    给出 array = [1,0,0,1,1,1] , 返回2。
    解释:
    把两个0翻转成1。
    
    给出 array = [1,0,1,0,1,0] , 返回2。
    解释:
    把第二个1和第三个1都翻转成0。
    

    注意事项

    输入的数组长度n <= 100000
    

    1.解题思路

      这道题是一道非常简单的动态规划题。不得不欣慰,自己花了不到20分钟的事件,把这道题做出来了,自己的动态规划终于好了那么一点点了!
      由于这道题非常的简单,这里我简单的介绍一下这道题的思路。假设dp[nums.length][2],其中dp[i][0],表示第i张牌变成0需要的最小步数,dp[i][1]意思也是如此。
      其中我们从题意中得到,1只能在1后面的,不能再0的后面。所以当nums[i] =1,dp[i][1] = dp[i - 1][1]这个肯定是正确的,但是dp[i ][0],由于nums为1,所以变为0需要需要旋转一次。从而得知,dp[i][0] = Math.min(dp[i - 1][1] + 1, dp[i - 1][0] + 1),首先从0到1,肯定会增加一步;其次0可以在1或者0的后面,所以,需要从上一步中取最小。
      当nums[i]= 0时,我们知道的值0可以在1或者0的后面,所以,dp[i][0] = Math.min(dp[i - 1][0], dp[i - 1][1]);同时我们还知道,1只能在1的后面,所以dp[i][1] = dp[i -1] + 1,这里之所以+1是因为nums[i]本来为1,要想变为dp[i][0]需要旋转一步。

    2.代码

        public int flipDigit(int[] nums) {
            int dp[][] = new int[nums.length][2];
            if (nums[0] == 1) {
                dp[0][1] = 0;
                dp[0][0] = 1;
            } else {
                dp[0][0] = 0;
                dp[0][1] = 1;
            }
            for (int i = 1; i < nums.length; i++) {
                if (nums[i] == 1) { //当nums[i] = 1时
                    //从1 变为0需要增加一步,同时0可以在1或者0的后面,所以需要取最小值
                    dp[i][0] = Math.min(dp[i - 1][1] + 1, dp[i - 1][0] + 1);
                    //不变,继承上一步
                    dp[i][1] = dp[i - 1][1];
    
                } else {
                    //0可以在1或者0的后面,由于它本身就是0,所以不需要增加步数
                    dp[i][0] = Math.min(dp[i - 1][0], dp[i - 1][1]);
                    //从0变为1需要增加步数
                    dp[i][1] = dp[i - 1][1] + 1;
                }
            }
    
            return Math.min(dp[nums.length - 1][0], dp[nums.length - 1][1]);
        }
    

    相关文章

      网友评论

        本文标题:Java 算法 - 数字翻转(动态规划)

        本文链接:https://www.haomeiwen.com/subject/yxmgfftx.html