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

又来到了今天的每日一题,距离上次更新每日一题得有十天了。

主要原因是这十天的题要么简单到爆,要么难到爆,再要么就是最近学校安排实训,时间比较紧。

废话不多说,来看看今天的题目。

题目很简单,就是给个数组,数组里的元素要么是0要么是1(成都?)

我们每次可以把三个连续的元素翻转,也就是0变1,1 变0,问我们最少操作几次可以把数组里的元素全部变成1。

数组首尾不相连,所以我们能翻转的三个元素的起点索引是(0 ~ n-2 (n为数组长度))。

这道题的通过率有77%,所以它实际上就是看着唬人,实际上不难。

我们一步步思考,我们第一步应该先翻转哪里?

如果数组第一个元素就是0,那么第一个元素是肯定要翻转的,而我们只有从索引0的位置开始翻转才可以翻转到第一个元素,其他位置都不行,所以这个翻转是逃不掉的。

翻转完之后第一个元素就是1了,那么我们是不是可以先把它排除在外?

因为它已经是1了,而只有从索引0的位置开始翻转才能改变到它,为了保持它始终为1,我们应该不再从索引0的位置翻转,既然如此,我们自然是可以把它排除在外。

排除之后,我们把之前索引1的位置当成新的索引0,然后重复上述过程......

大家拿纸笔找个示例画一画就明白了。

我们"排除"的时候并不需要把这个元素从数组中删除,我们只需要移动索引指针即可,并且因为翻转的起点位置范围是0~n-2,所以要控制一下for循环的范围。

示例代码如下:

cpp 复制代码
class Solution {
public:
    int minOperations(vector<int>& nums) {
        int n = nums.size();
        int res = 0;
        for(int i = 0; i < n - 2; ++i){
            if(nums[i] != 1){   // 如果不等于1,那么需要翻转
                ++res;
                nums[i + 1] = nums[i + 1] == 1 ? 0 : 1;     // 翻转后两位
                nums[i + 2] = nums[i + 2] == 1 ? 0 : 1;
            }
        }
        // 若数组最后两位都为1,那么可以操作,反之无法都变成1.
        if(nums[n - 1] == 1 && nums[n - 2] == 1) return res;
        return -1;
    }
};

合理推测明天的每日一题是下面这道。

翻转三次改成了翻转剩余元素。

如果按照上一题的做法做的话是会超时的,因为翻转而循环的次数太多了,如果是剩余的元素都要翻转,实际上我们可以不去真的翻转。

具体怎么做明天再说,我还要水一篇文呢。

相关推荐
啦啦啦啦啦zzzz4 分钟前
moduo网络库 Acceptor TcpConnection
服务器·网络·c++·reactor·网络库
键盘会跳舞6 分钟前
C++:右值引用与移动语义源码级深度拆解——现代C++性能优化的语言基石
c++·右值引用·移动语义
码匠许师傅15 分钟前
【C++ 面试真题】聊聊 C++ 的虚函数和多态
java·c++·面试
LuminousCPP31 分钟前
单链表专题(四)-刷题复盘篇-LeetCode 138 随机链表复制|原地拷贝法突破复杂指针操作
数据结构·笔记·算法·leetcode·链表
逆境不可逃1 小时前
【LeetCode 912】排序数组——随机化快速排序详解
数据结构·算法·排序算法
Coder-magician1 小时前
《代码随想录》刷题打卡day31:动态规划-背包问题part02
算法·动态规划
薛定e的猫咪1 小时前
从因果视角解决多智能体协作:细读 SCIC 算法
算法
Forever Nore1 小时前
LeetCode 14 最长公共前缀 - 纵向扫描
linux·服务器·leetcode
c238561 小时前
《算法武林谱:四大排序神功与二分寻宝术全解》
数据结构·算法·排序算法
圣保罗的大教堂1 小时前
leetcode 3090. 每个字符最多出现两次的最长子字符串 简单
leetcode