原题

In an array A containing only 0s and 1s, a K-bit flip consists of choosing a (contiguous) subarray of length K and simultaneously changing every 0 in the subarray to 1, and every 1 in the subarray to 0.

Return the minimum number of K-bit flips required so that there is no 0 in the array. If it is not possible, return -1.

Example 1:

Input: A = [0,1,0], K = 1
Output: 2
Explanation: Flip A[0], then flip A[2].

Example 2:

Input: A = [1,1,0], K = 2
Output: -1
Explanation: No matter how we flip subarrays of size 2, we can't make the array become [1,1,1].

Example 3:

Input: A = [0,0,0,1,0,1,1,0], K = 3
Output: 3
Explanation:
Flip A[0],A[1],A[2]: A becomes [1,1,1,1,0,1,1,0]
Flip A[4],A[5],A[6]: A becomes [1,1,1,1,1,0,0,0]
Flip A[5],A[6],A[7]: A becomes [1,1,1,1,1,1,1,1]

Note:

1 <= A.length <= 30000
1 <= K <= A.length

分析

在给出一个0, 1序列后,可以对其中连续K个数字进行翻转(0翻转为1,1翻转为0)。如果想要全部翻转为1,那么直观的一个感受就是从左到右,如果当前位置的数字是0,那么可以作为需要翻转的连续K个数字的起点,因此最简单的思路:

  1. 从左到右,寻找值为0的下标index
  2. 对A[index, index + K-1]的数字进行翻转
  3. 重复1, 2,直至数组值全为1,或者index + K > A.length为止

拍脑门解法

Note:需要注意的一点是,在进行翻转的时候所采取的方法决定是否超时,用^进行异或操作会减少用时,特别地,与1异或表示对当前位进行翻转

Accept代码

class Solution {public:bool flip(vector<int> & A, int K, int pos) {if (pos + K > A.size())return false;for (int i = pos; i < pos + K; ++i) {A[i] ^= 1;}return true;}int minKBitFlips(vector<int>& A, int K) {int n = A.size();int ans = 0, last_pos = 0; for (int i = 0; i < n; ++i) {if (A[i] == 0) {ans++;if (!flip(A, K, i))return -1;}}return ans;}
};

在上面的解法中,之前用if else语句对A数组值进行翻转,结果超时

bool flip(vector<int> & A, int K, int pos) {if (pos + K > A.size())return false;for (int i = pos; i < pos + K; ++i) {//超时代码if(A[i] == 1)A[i] = 0;else A[i] = 1;}return true;}

这个方法速度很慢,用时5216 ms,在超时的边缘徘徊,于是借鉴别人的解法。

他山之石,可以攻玉(别人的答案)

在提交之后可以看到别人提交的答案,看完后再看看自己的代码便更觉得羞涩难挡,因此去掉了贴自己代码这一步,转而分析别人代码。

作者@awice

思路:
之前的贪心算法虽然可以成功运行,但是耗时较长(主要耗时的部分在翻转A[index, index+K-1]部分,当次翻转范围与上次翻转范围存在重叠,当重叠部分进行翻转的两次的时候,相当于没有翻转,造成了时间的浪费)。因此用一个flip位来记录当前K个连续数字是否已经翻转,用一个hint数组来记录翻转。

算法流程:

  1. 初始化flip =0, hint数组为0

  2. 遍历数组A,

  3. flip ^= hint[i], 异或运算后flip位表示当前位置i是否被翻转过,flip=0,未翻转,flip=1,翻转。hint数组用来记录翻转,(特别地,当A[i]需要翻转时,hint[i + K]记录翻转截止范围,见下面第4步骤)

  4. 判断A[i] == flip,

    • A[i]与flip均为0时,表示A[i] = 0且当前位未被翻转,需要进行翻转
    • A[i]与flip均为1时,表示A[i] = 1且当前位已被翻转(实际值为0),需要再次翻转

    若A[i] == flip, 表明需要进行翻转

    • 翻转次数加一,ans++
    • 判断i+K是否超出A数组长度,超出则失败返回-1
    • 对flip位进行翻转
    • 对hint[i+K]位进行翻转
class Solution {public:int minKBitFlips(vector<int>& A, int K) {int n = A.size();vector<int> hint(n, 0);int ans = 0, flip = 0;for (int i = 0; i < n; ++i) {flip ^= hint[i];if (A[i] == flip) {ans++;if (i + K > n)return -1;flip ^= 1;if (i + K < n)hint[i + K] ^= 1;}}return ans;}
};

使用改进算法对重叠的部分进行索引记录后,程序运行时间大大减少,为112ms,缩短了近50倍。果然还是别人的饭吃起来香~

Leetcode 995. Minimum Number of K Consecutive Bit Flips相关推荐

  1. LeetCode-995. K连续位的最小翻转次数(Minimum Number of K Consecutive Bit Flips)

    K连续位的最小翻转次数 在仅包含 0 和 1 的数组 A 中,一次 K 位翻转包括选择一个长度为 K 的(连续)子数组,同时将子数组中的每个 0 更改为 1,而每个 1 更改为 0. 返回所需的 K ...

  2. LeetCode 871. Minimum Number of Refueling Stops 最少加油次数

    LeetCode 871. Minimum Number of Refueling Stops 本题是LeetCode 871题,最少加油次数. 题目描述 A car travels from a s ...

  3. LeetCode: 871. Minimum Number of Refueling Stops

    LeetCode: 871. Minimum Number of Refueling Stops 题目描述 A car travels from a starting position to a de ...

  4. LeetCode 452 Minimum Number of Arrows to Burst Balloons(贪心法)

    问题:给出n个气球,已知其在二维平面中的区间[left,right],箭只能竖直向中,气球重叠时,箭仍然可以穿过.问最少需要多少箭. 思路:贪心算法,根据右端点从小到大排序.在遍历区间时,如果当前区间 ...

  5. leetcode 452. Minimum Number of Arrows to Burst Balloons | 452. 用最少数量的箭引爆气球(左程云:最大线段重合问题)

    题目 https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/ 题解 重叠区间问题可以总结为在坐标轴上若干个位 ...

  6. [LeetCode] 871. Minimum Number of Refueling Stops

    题:https://leetcode.com/problems/minimum-number-of-refueling-stops/ 题目大意 起点有油 startFuel 的车,想行驶到 终点 ta ...

  7. [LeetCode] 871. Minimum Number of Refueling Stops @ python

    一.题目: 初始油量startFuel,给一个到达目的地所需的油量target,还有沿途的加油站stations(包括到达加油站所需油量以及储备的油量),求达到目的地所需的最少加油次数,如果到不了返回 ...

  8. LeetCode——1888. 使二进制字符串字符交替的最少反转次数(Minimum Number of Flips to Make the Binary ...)[中等]——分析及代码(Java)

    LeetCode--1888. 使二进制字符串字符交替的最少反转次数[Minimum Number of Flips to Make the Binary String Alternating][中等 ...

  9. LeetCode刷题:871. Minimum Number of Refueling Stops

    LeetCode刷题:871. Minimum Number of Refueling Stops 原题链接:https://leetcode.com/problems/minimum-number- ...

  10. LeetCode 202次周赛 1553. Minimum Number of Days to Eat N Oranges

    1553. Minimum Number of Days to Eat N Oranges 题目描述 思路分析 弱智动态规划 可行的动态规划 直觉上正确的思路 代码实现 证明正确性 复杂度分析 总结 ...

最新文章

  1. 精心推荐10个高质量的网站,打开新世界的大门
  2. linux下查看vnc端口_怎样查vnc端口,Linux下根据进程名怎样查端口
  3. pull to load more data
  4. 「后端小伙伴来学前端了」Vue中学会使用Echarts生成各种各样的图表,得学学了,必须要会的基本操作了
  5. linux sudo永久免密码,linux 免密码 使用sudo 直接使用root权限执行命令
  6. 利用indent格式化源文件的脚本
  7. execjs执行报: ‘gbk‘ codec can‘t decode byte 0xac in position 62: illegal multibyte sequence
  8. ENVI学习总结(六)——图像自动配准
  9. 第三章 文本与列表控制
  10. 用c语言编写文本游戏,如何用C语言编写游戏.doc
  11. SQL替换字段中的部分内容
  12. rtk定位权限_无人机中的GPS定位、DGPS差分定位、RTK差分定位
  13. 华为网络计算机登陆,华为路由器如何登录192.168.3.1入口设置界面
  14. 肺疫面前,段子手出动,但是玩笑也要分场合
  15. [qt]qt下载地址
  16. 基于cc3200开发
  17. 刘强东隐退:卸任京东CEO
  18. android手机几个目录的介绍:/system/app; /system/vender;/data/app;/data/dalvik-cache;/mnt/asec;/mnt/secure
  19. better—scrolls解决下拉刷新,上拉加载更多时出现只执行一次的问题
  20. 【托业】【跨栏】TEST05

热门文章

  1. numpy: np.asarray 函数
  2. Fresco图片库研读分析
  3. macbook重装系统 选择方案_Mac重装系统教程(二):网络在线重装系统
  4. word文档删除空白页,选中空白页面按住 delete
  5. [FOI2020]手链强化
  6. FOI对象中显示labels --Oracle Map
  7. 爬虫——八爪鱼采集器
  8. win10快捷键整理记录
  9. 【图像识别】人脸识别原理及CNN讲解
  10. Android 13运行时权限变更一览