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;
    }
};
目录
相关文章
|
11月前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
2557 44
|
10月前
|
运维
【10月更文挑战赛】获奖名单出炉,快来看看谁是十月创作明星!
【10月更文挑战赛】获奖名单出炉,快来看看谁是十月创作明星!
309 9
|
11月前
|
前端开发 Java 数据库
SpringBoot学习
【10月更文挑战第7天】Spring学习
124 9
|
11月前
|
druid Java Maven
|
10月前
3331. 修改后子树的大小
【10月更文挑战第11天】3331. 修改后子树的大小
74 7
|
11月前
|
人工智能
字符串转换后的长度
【10月更文挑战第10天】字符串转换后的长度I,字符串转换后的长度II
97 1
|
11月前
|
JavaScript
力扣3333.找到初始输入字符串Ⅱ
【10月更文挑战第9天】力扣3333.找到初始输入字符串Ⅱ
112 1
|
11月前
|
XML Java 数据格式
Spring学习
【10月更文挑战第6天】Spring学习
82 1
简单易操作 VsCoe离线安装插件【步骤+图片+插件】
这篇文章介绍了在Visual Studio Code (VSCode) 中进行离线安装插件的详细步骤,包括如何下载插件、以SVN插件为例的离线安装过程、通过命令行安装以及一个更加简单的离线安装方式,还提供了操作界面的截图帮助理解。
简单易操作 VsCoe离线安装插件【步骤+图片+插件】
|
11月前
|
前端开发 Java 数据库连接
javamvc配置,增删改查,文件上传下载。
【10月更文挑战第4天】javamvc配置,增删改查,文件上传下载。
85 1