题目链接:力扣
https://leetcode-cn.com/problems/non-negative-integers-without-consecutive-ones/
题意:给定一个正整数 n,找出小于或等于 n 的非负整数中,其二进制表示不包含 连续的1 的个数。
方法: 动态规划,利用位运算,dp[i]表示第i位是1其余位全是0的情况下,不包含连续1的个数,每次通过位运算枚举当前最高位k的数是否为1,假如是的话就加上dp[k]的情况数目,然后判断一下前一位是否是1,假如是的话,就说明出现了连续两个1的情况,可以结束了,没必要继续做了,直接返回对应的结果,假如不连续,更新对应的pre为1,表示出现了1。
假如到了最后返回的情况时,说明没有出现连续1的情况,必须加上自己本身这个数,因为不重复,然后将结果返回
class Solution {
public:
int findIntegers(int n) {
vector<int> dp(32);//动态规划向量
dp[0] = 1;//初始化状态,0位的时候,一种情况
dp[1] = 2;//1位的时候2种情况
for(int i=2;i<32;i++)
{
dp[i] = dp[i-1] + dp[i-2];//更新dp向量
}
int ans = 0;//结果
int pre = 0;//记录前一位是不是1
for(int k=31;k>=0;k--)//移位,移动k位
{
int tmp = 1<<k;//暂存1左移k位以后的数字
if((tmp&n)!=0)//第k位是1
{
ans += dp[k];//加上对应的情况数目
if(pre==1) return ans;//假如前一位是1,就返回结果,没必要在错误的路上继续下去
pre = 1;//假如pre不是1,更新pre,因为相对下一轮来说,这一轮已经变成前一轮了
}else//前一位是0,就更新pre
{
pre = 0;
}
}
return ans+1;//返回结果位ans+1,因为如果是正常结束的情况,说明不存在连续的1,要加上自己本身那个数
}
};

该博客探讨了LeetCode中的问题600,涉及寻找不超过n的非负整数,这些整数在二进制表示中不包含连续的1。解决方法是采用动态规划和位运算,通过维护一个dp数组记录当前位为1且之前无连续1的数的数量。在枚举过程中,根据前一位的状态决定是否增加计数,并在结束时考虑包含当前位1的情况。
361

被折叠的 条评论
为什么被折叠?



