LeetCode 每日一题 使二进制数组全部等于 1 的最少操作次数 I

时间:2024-10-19 08:13:49

使二进制数组全部等于 1 的最少操作次数 I

给你一个二进制数组 nums 。
你可以对数组执行以下操作 任意 次(也可以 0 次):
选择数组中 任意连续 3 个元素,并将它们 全部反转 。
反转 一个元素指的是将它的值从 0 变 1 ,或者从 1 变 0 。
请你返回将 nums 中所有元素变为 1 的 最少 操作次数。如果无法全部变成 1 ,返回 -1 。
示例 1:
输入:nums = [0,1,1,1,0,0]
输出:3
解释:
我们可以执行以下操作:
选择下标为 0 ,1 和 2 的元素并反转,得到 nums = [1,0,0,1,0,0] 。
选择下标为 1 ,2 和 3 的元素并反转,得到 nums = [1,1,1,0,0,0] 。
选择下标为 3 ,4 和 5 的元素并反转,得到 nums = [1,1,1,1,1,1] 。
示例 2:
输入:nums = [0,1,1,1]
输出:-1
解释:
无法将所有元素都变为 1 。
提示:
3 <= nums.length <= 105
0 <= nums[i] <= 1

题解

根据题意,我们需要进行将一个数组的第 i 到 i+2 的元素 ^ 1 ,使得数组的全部元素变成1

求得这一操作的最少次数

如果无法全部变成 1 就返回 -1

首先,我们对操作进行思考

对一个位置 i ,最多只能进行一次操作,因为操作两次就相当于没有操作,白白浪费次数,更多次数同理

接着

操作的顺序对结果是没有影响的,先对 i 操作再 操作 j 与先 j 后 i 得到的结果是一致的

那么也就是说,对于任意的操作,操作的顺序可以是任意

我们不妨从左至右进行操作

用 res 记录操作次数

对数组进行遍历,最多遍历到倒数第三个,因为要对位置的后两个进行操作,防止越界

假如此时数据是 1 则不进行操作,i++

如果此时数据是 0 则必须要操作,否则不可能使数组全为 1 ,即对 i 至 i+2 的数据 ^ 1 ,res++,i++

循环结束的时候,假如数组的最后两个数据都是 1 则说明数组全是1,返回 res

否则说明无法达到全是1,返回 -1

那么为什么这样操作就是最少的次数呢?
因为对同一个 i 至多操作一次,就可以做到最少的操作次数

代码如下↓

int minOperations(int* nums, int numsSize) {
    int res=0;
    for(int i=0;i<numsSize-2;i++)
    {
        if(nums[i]==1)
        {
            continue;
        }
        else
        {
            nums[i]^=1;
            nums[i+1]^=1;
            nums[i+2]^=1;
            res++;
        }
    }
    if(nums[numsSize-2] && nums[numsSize-1])
    {
        return res;
    }
    else
    {
        return -1;
    }
}