文章目录
面试题 05.03. 翻转数位
一、题目描述
给定一个32位整数 num,你可以将一个数位从0变为1。请编写一个程序,找出你能够获得的最长的一串1的长度。
二、思路
标签又是动态规划,但是 完全可以使用 滑动窗口思想 再加上位运算!
感叹 位运算是真的强大。
二者还不太懂 先去补补课。
滑动窗口
位运算
由于我们不知道给定十进制数的位数,但是题目说的是给定32位整数,那么二进制最长32位,(长度不够高位补0),我们就循环32次 。
循环过程:
每次num的最低位都按位与 1 ,结果等于1,说明最低位为1,长度+1,然后num右移一位;
如果结果不等于 1,并且当前有一位可用(可将0变为1),那么 这个最低位也相当于1,长度+1 ,至此以后再也没有可用位变1了,记录这个位置,num继续右移;
如果当前没有可用位将0变1,开始滑动, 将窗口右端 滑动到 上一个记录位置 (即 将当前的最大值更改 为 当前位置-上一个记录位置),并且更新记录位置为当前位置。num继续右移。
注意: 因为移动过程中,当前最大值可能发生滑动(即 不一定总是递增,有可能窗口滑动,将最大值改小了),所以我们每次都要保存长度最大值。
三、代码
class Solution {
public:
int reverseBits(int num) {
//l 记录位数
//k 记录当前是否可将0变为1
int l=0,sum=0,k=0,f=0,max_len=0;
while(l<32){
//当前位等于1
if(num&1==1){
sum++;
//当前位等于0 但是可以将该0位转成1
}else if(k==0){
f=l;
k++;
sum++;
//当前位为0 不能够转成1了,
}else{
//更改当前最大值
sum=l-f;
f=l;
}
//更新最大值
if(sum>max_len){
max_len=sum;
}
l++;
num>>=1;
}
return max_len;
}
};