LintCode-数字翻转

843. 数字翻转

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

注意事项
  • 输入的数组长度n <= 100000

样例

给出 array = [1,0,0,1,1,1] , 返回2

解释:
把两个0翻转成1。

给出 array = [1,0,1,0,1,0] , 返回2

解释:
把第二个1和第三个1都翻转成0。

这题标签上写了动态规划,但感觉算不上。
对于长度为n的数组,只有n+1种反转后的状态,对于样例就是:
0,0,0,0,0,0
1,0,0,0,0,0
1,1,0,0,0,0
…..
1,1,1,1,1,1
因此可以先假设全翻转为0,记录1的个数t(需要1->0翻转的次数),然后从头开始遍历,使第i位之前都是1,第i位之后都是0。
具体操作就是遇到i=1时t-1(不需要翻转,但上面假设已经翻转过了,要再减回去),遇到i=0时t+1(多一次翻转),每次操作后更新t的最小值。

class Solution {
public:
    /**
     * @param nums: the array
     * @return: the minimum times to flip digit
     */
    int flipDigit(vector<int> &nums) {
        // Write your code here
        int t=0,min=INT32_MAX;
        for(auto& i:nums)
        {
            if(i==1) t++;
        }
        for(auto& i:nums)
        {
            if(i==0) t++;
            if(i==1) t--;
            min=t<min?t:min;
        }
        return min;
    }
};

但这些判断很耗时间,可以做一些优化,改完后运行时间快了四五倍。

class Solution {
public:
    /**
     * @param nums: the array
     * @return: the minimum times to flip digit
     */
    int flipDigit(vector<int> &nums) {
        // Write your code here
        int t=0,min=INT32_MAX;
        for(auto& i:nums)
        {
            t+=i;
        }
        for(auto& i:nums)
        {
            t-=(i-0.5f)*2;
            min=t<min?t:min;
        }
        return min;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值