5.3 Flip Bit to Win

The first method to solve this problem is using O(k) time w/ O(k) memory where k indicates length of input in binary form.

    //java code:
    public class program {
    public static int longestSequence(int n) {
        if (n == -1) return 32;
        ArrayList<Integer> sequences = getSeq(n);
        for(int i = 0; i<sequences.size(); ++i ){
            System.out.print(i + " => ");
            System.out.println(sequences.get(i));
        }
        return findSeq(sequences);
    }   

    /* Return a list of the sizes of the sequences. The sequence starts 
     * off with the number of 0s (which might be 0) and then alternates
     * with the counts of each value.*/
    public static ArrayList<Integer> getSeq(int n){
        ArrayList<Integer> seq = new ArrayList<Integer>();
        int searchFor = 0, cnt = 0;
        for(int i = 0; i<32; ++i){
            if ((n & 1) != searchFor){
                seq.add(cnt);
                searchFor = n & 1;// try to find another bit(0 or 1);
                cnt = 0;
            }
            ++cnt;
            n >>= 1;
        }
        seq.add(cnt);
        return seq;
    }
    public static int findSeq(ArrayList<Integer> seq){
        int maxSeq = 1;
        for(int i = 0; i<seq.size(); i += 2){
            int zeroSeq = seq.get(i);
            int leftOneSeq = ((i + 1) < seq.size()) ? seq.get( i+1 ) : 0;
            int rightOneSeq = ((i-1) >= 0) ? seq.get(i-1) : 0;
            if(zeroSeq > 1) maxSeq = Math.max(maxSeq, (Math.max(leftOneSeq, rightOneSeq) + 1));// there are at least two 0s together, but we can only change one!
            else if(zeroSeq == 1) maxSeq = Math.max(leftOneSeq + rightOneSeq + 1, maxSeq);
            else maxSeq = Math.max(Math.max(leftOneSeq, rightOneSeq), maxSeq);
        }
        return maxSeq;
    }   
    public static void main(String[] args) {
        int original_number = 1775;
        int new_number = longestSequence(original_number);      System.out.println(Integer.toBinaryString(original_number));
        System.out.println(new_number);             
    }
}

c++ code:

    vector<int> getSeq( int n){
        int searchFor = 0, cnt = 0;
        vector<int> seq;
        for (int i = 0; i<32; ++i) {
            if ((n&1)!= searchFor){
                seq.push_back(cnt);
                searchFor = n & 1;
                cnt = 0;
            }
            ++cnt;
            n >>= 1;
        }
        return seq;
    }

    int findSeq(vector<int>& seq){
        int maxSeq = 1;
        for (int i = 0; i<seq.size(); ++i) {
            int zeroSeq = seq[i], left = (i+1) < seq.size() ? seq[i+1] : 0, right = (i-1)>=0 ? seq[i-1] : 0;
            if (zeroSeq > 1) maxSeq = max(maxSeq, max(left, right)+1);
            else if(zeroSeq == 1) maxSeq = max(maxSeq, left + right + 1);
            else maxSeq = max(maxSeq, max(left, right));
        }
        return maxSeq;
    }
    int findLongestSeq(int n){
        if (n==-1) return 32;
        vector<int> seq = getSeq(n);
        return findSeq(seq);
    }

Optimize: only keep leftOneSeq, zeroSeq, rightOneSeq each time by using * int[] seq = { 0, 0, 0 } * . The memory reduces to O(1);

    public class program {

    static int findMax(int[] seq){
        if(seq[1] == 1) return seq[0] + seq[1] + 1;
        else if(seq[1] == 0) return Math.max(seq[0], seq[2]);
        else return Math.max(seq[0], seq[2]) + 1;
    }

    static void shift(int[] seq){
        seq[2] = seq[1];
        seq[1] = seq[0];
        seq[0] = 0;
    }
    public static int longestSequence(int n) {
        if (n == -1) return Integer.BYTES * 8;
        int[] seq = {0, 0, 0};
        int maxSeq = 1, searchFor = 0;
        for(int i =0; i<32; ++i){
            if((n & 1) != searchFor){
                if(searchFor == 1) maxSeq = Math.max(maxSeq, findMax(seq));//we already find two 1s seq;
                searchFor = n & 1;
                shift(seq);
            }
            seq[0]++;// if we are searching what we want, just keep updating seq[0].
            n >>= 1;//if we want to shif sign as well, we should use n >>>= 1;
        }
        return maxSeq;
    }   

    public static void main(String[] args) {
        int original_number = 2222;
        int new_number = longestSequence(original_number);

        System.out.println(Integer.toBinaryString(original_number));
        System.out.println(new_number);             
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值