zoukankan      html  css  js  c++  java
  • [leetcode] Minimum Number of K Consecutive Bit Flips

    我永远都学不会贪心算法罢了(╯‵□′)╯︵┻━┻

    用队列flip_records记录翻转情况,flip_records中每个int元素记录一次翻转操作的起始位置。i.e. 元素值为start代表A[start]到A[start+k-1]的牌被翻转过。

    从左到右遍历A中所有的牌,对每个当前遍历到的位置i:

        1. 检查flip_records队列中最前的位置记录(记为front),如果front+k-1<i,说明这次最早的翻转操作对当前的i没有影响,直接把这条记录从flip_records中弹出。

        2. 用bool变量need_flip表示当前是否需要增加(以i为起始位置的)翻转操作,need_flip的值可以这样计算:

            2-1. 因为先前做过弹出检查,所以当前flip_records中的翻转记录肯定都是对牌i有影响的。如果牌i在先前被翻转过偶数次则相当于没有翻转过。

                   所以,用has_flipped记录牌“实际上相当于有没有翻转过”,has_flipped由flip_records队列中元素数量的奇偶决定。

            2-2. 然后,根据A[i]和has_flipped的值计算need_flip:

                   //A[i]为0,实际上相当没有翻转过,则需要翻转,etc。

    A[i] has_flipped need_flip
    0 0 1
    0 1 0
    1 0 0
    1 1 1

             2-3. 如果need_flip为真,说明牌i需要翻转。首先检查这次翻转会不会越界,如果越界说明不能成功,直接返回-1;如果可以翻转,递增翻转次数count。

    最后返回翻转次数count。 

    class Solution {
    public:
        int minKBitFlips(vector<int>& A, int K) {
            int count=0, A_length=A.size();
            queue<int> flip_records;
            bool has_flipped, need_flip;
            for (int i=0;i<A_length;i++) {
                if (!flip_records.empty()) {
                    if (flip_records.front()+K-1<i)
                        flip_records.pop();
                }
                has_flipped=flip_records.size()%2?true:false;
                need_flip=!A[i]^has_flipped;
                if (need_flip) {
                    if (i+K>A_length)
                        return -1;
                    flip_records.push(i);
                    ++count;
                }
            }
            return count;
        }
    };
  • 相关阅读:
    第一次作业
    第0次作业
    第14、15周作业
    第七周作业
    第六周作业
    第四周作业
    第三周作业
    第4次作业
    第3次作业
    第二次作业
  • 原文地址:https://www.cnblogs.com/RDaneelOlivaw/p/10464772.html
Copyright © 2011-2022 走看看