Bootstrap

LeetCode-3192 使二进制数组全部等于1的最少操作次数Ⅱ

今天的每日一题就是昨天的延伸,预判成功。

LeetCode-3191 使二进制数组全部等于1的最少操作次数-CSDN博客文章浏览阅读115次。如果数组第一个元素就是0,那么第一个元素是肯定要翻转的,而我们只有从索引0的位置开始翻转才可以翻转到第一个元素,其他位置都不行,所以这个翻转是逃不掉的。因为它已经是1了,而只有从索引0的位置开始翻转才能改变到它,为了保持它始终为1,我们应该不再从索引0的位置翻转,既然如此,我们自然是可以把它排除在外。如果按照上一题的做法做的话是会超时的,因为翻转而循环的次数太多了,如果是剩余的元素都要翻转,实际上我们可以不去真的翻转。主要原因是这十天的题要么简单到爆,要么难到爆,再要么就是最近学校安排实训,时间比较紧。https://blog.csdn.net/m0_63235356/article/details/143033045?spm=1001.2014.3001.5501

解法其实差不多,但是如果我们真的按照昨天的方法一个个去模拟翻转是会超时的。因为昨天是翻转三个,而今天是翻转右边所有。

思路是一样的,我们要翻转数组左侧第一个元素的话只能从索引为0的位置开始翻转,所以还是要从左往右开始遇0翻转。

问题在于我们不能像昨天一样真的把后面的元素一个个翻转。

因为我们是从左侧开始遍历,所以如果我遇到0了,那么后续所有元素都需要翻转,因此我们只需要额外拿一个变量来记录翻转次数即可。

因为翻两次等于没返,所以如果累计翻转次数为奇数并且当前元素的值为0或者是累计翻转次数为偶数并且当前元素的值为1,这两种情况下不需要翻转,反之需要翻转,把记录次数的变量++即可。

不难理解,可以参考着下面的代码自己动手敲一敲,跟昨天的每日一题思路是一致的。

class Solution {
public:
    int minOperations(vector<int>& nums) {
        int n = nums.size();
        int res = 0, temp = 0;  // temp 记录翻转次数
        for(int i = 0; i < n; ++i){
            if((temp%2 == 0 && nums[i] == 0) || (temp%2 == 1 && nums[i] == 1)){
                res++,temp++;
            }
        }
        return res;
    }
};

;