3191. 使二进制数组全部等于 1 的最少操作次数 I 和3192. 使二进制数组全部等于 1 的最少操作次数 II

简介: 【10月更文挑战第2天】3191. 使二进制数组全部等于 1 的最少操作次数 I 和3192. 使二进制数组全部等于 1 的最少操作次数 II

3191 使二进制数组全部等于 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 <= 10^5$
$0 <= nums[i] <= 1$

思路:

这个题要求连续三个数反转,所以我们可以直接从头开始计算,

  • 如果第一个是0,那么说明我们需要反转一次,(也就是第一个,第二个和第三个都需要反转)。
  • 如果第一个是1,则说明我们不需要操作。
  • 然后我们再看二个,与第一个相同,这里要注意我们前面第一个如果是0我们是对第二个反转了一遍。之后就是相同的操作。

整体就是按顺序进行模拟。

class Solution {
public:
    int minOperations(vector<int>& nums) {
        int n=nums.size();        
        int ans=0;        
        for(int i=2;i<n;i++){
            if(nums[i-2]==0){
                nums[i-2]=1;
                nums[i-1]^=1;
                nums[i]^=1;
                ans++;
            }
        }
        if(nums[n-1]==0||nums[n-2]==0) return -1;
        return ans;
    }
};

进阶版 3192. 使二进制数组全部等于 1 的最少操作次数 II

给你一个二进制数组 nums 。

你可以对数组执行以下操作 任意 次(也可以 0 次):

选择数组中 任意 一个下标 i ,并将从下标 i 开始一直到数组末尾 所有 元素 反转 。
反转 一个元素指的是将它的值从 0 变 1 ,或者从 1 变 0 。

请你返回将 nums 中所有元素变为 1 的 最少 操作次数。

示例 1:

输入:nums = [0,1,1,0,1]

输出:4

解释:
我们可以执行以下操作:

选择下标 i = 1 执行操作,得到 nums = [0,0,0,1,0] 。
选择下标 i = 0 执行操作,得到 nums = [1,1,1,0,1] 。
选择下标 i = 4 执行操作,得到 nums = [1,1,1,0,0] 。
选择下标 i = 3 执行操作,得到 nums = [1,1,1,1,1] 。
示例 2:

输入:nums = [1,0,0,0]

输出:1

解释:
我们可以执行以下操作:

选择下标 i = 1 执行操作,得到 nums = [1,1,1,1] 。

提示:

$1 <= nums.length <= 105$
$0 <= nums[i] <= 1$

思路:

这个题要求i后面都反转,同样的我们可以直接从头开始计算,(模拟):
如果前面i-1位都已经符合条件,并且需要反转x次。那么我看来第i位。

  • 如果第i位是0,经过x次转换后,它应该是y=(0+x)%2,
  • 如果第i位是1,经过x次转换后,它应该是y=(1+x)%2
  • 如果y是0,则说明在第i位上需要反转一次。那么i位后的位置需要反转x+1次。
  • 如果y是1,则说明在第i位上就不需要操作了。

整体就是按顺序进行模拟。

class Solution {
public:
    int minOperations(vector<int>& nums) {
        int n=nums.size();        
        int ans=0; 
        int flag=0;       
        for(int i=0;i<n;i++){
            if((nums[i]+flag)%2==0){
                flag^=1;                
                ans++;
            }
        }
        return ans;
    }
};
目录
相关文章
|
7月前
给定 n 个整数,求里面出现次数最多的数,如果有多个重复出现的数,求值最大的那个 给定n个整数,求里面出现次数最多的数,如果有多个重复出现的数,求出值最大的一
给定 n 个整数,求里面出现次数最多的数,如果有多个重复出现的数,求值最大的那个 给定n个整数,求里面出现次数最多的数,如果有多个重复出现的数,求出值最大的一
|
1月前
使用函数判断Armstrong 数
【10月更文挑战第24天】使用函数判断Armstrong 数。
20 7
|
7月前
2.任意输入三个数,求最大数
2.任意输入三个数,求最大数
39 0
|
7月前
|
存储 负载均衡 算法
负载均衡案例:如何只用2GB内存统计20亿个整数中出现次数最多的整数
负载均衡案例:如何只用2GB内存统计20亿个整数中出现次数最多的整数
109 2
|
C++
C++读取一行内个数不定的整数的方式
C++读取一行内个数不定的整数的方式
155 0
|
Shell Perl
查找 80 端口请求数最高的前 20 个 IP 地址,判断中间最小的请求数是否大于 500,如大于 500,则输出系统活动情况报告到 alert.txt,如果没有,则在 600s 后重试,直到有输出为止
查找 80 端口请求数最高的前 20 个 IP 地址,判断中间最小的请求数是否大于 500,如大于 500,则输出系统活动情况报告到 alert.txt,如果没有,则在 600s 后重试,直到有输出为止
102 1
1245:不重复地输出数 2020-12-28
1245:不重复地输出数 2020-12-28
|
机器学习/深度学习
【每日一题Day84】LC2283判断一个数的数字计数是否等于数位的值 | 哈希表
思路:使用哈希表统计每个数字出现的次数,再与字符串中的次数进行比较,如果所有数字次数均等于字符串中的次数,返回true;反之,返回false
61 0