LeetCode - 600. Non-negative Integers without Consecutive Ones

解题代码:

classSolution {

public:

    int findIntegers(int num) {

        if(num==0)

            return 1;

        if(num==1)

            return 2;

        if(num<=3)

            return 3;

        int i=2,j=0;

        while(num>=i){

            i*=2;

            j++;

        }

        if(num>=3*i/4){

            int a=2,b=3,s=1;

            while(s

                int t=a+b;

                a=b;

                b=t;

                s++;

            }

            return b;

        }

        else{

            int a=2,b=3,s=1;

            while(s

                int t=a+b;

                a=b;

                b=t;

                s++;

            }

            return b+findIntegers(num-i/2);

        }

    }

};

解题思路:

根据本题的要求,给出一个整数num,要求返回在小于等于num的非负整数中,二进制的形态下没有连续的1的数的个数。首先我们观察规律,可以发现如下的特性:

1.对于[2i, 2i+1)区间而言,里面数字的个数共有2i个,把它们分成两半,后面的2i-1个数字必然都是有相连的1的,而对于前2i-1个数字,它们是否存在连续1的情况分别与[0,2i-1)一一对应,也即是相同。

2.若要求小于2i的数中二进制中没有连续1的数的个数,可以设为a[i]。我们可以观察规律,若i=1,有a[i]=2,若i=2,a[i]=3,若i=3,a[i]=5……对于更普遍的情况,a[i]= a[i-1]+a[i-2]

根据上述的特性,我们可以完成题目的要求:首先我们分析num属于哪个区间,也即是找到[2i, 2i+1)使得num在这个区间里面。然后我们再研究,若num在这个区间的后2i-1个数字中,我们可以直接认为,答案就等于小于2i+1的数中二进制中没有连续1的数的个数。

而若num在区间的前2i-1个数字中,我们可以把需要求的分解成求小于2i的数中二进制中没有连续1的数的个数加上2i到num的数中二进制中没有连续1的数的个数。而上面后者其实相当于就是求小于等于num-2i的数中二进制中没有连续1的数的个数。

你可能感兴趣的:(LeetCode - 600. Non-negative Integers without Consecutive Ones)