题目描述
给定一个32位整数 num,你可以将一个数位从0变为1。请编写一个程序,找出你能够获得的最长的一串1的长度。
示例 1:
- 输入: num = 1775(110111011112)
输出: 8
示例 2:
- 输入: num = 7(01112)
输出: 4
解题思路与代码
这道题的解法涉及到位运算,如果对位运算不太了解的话,请看我这篇文章扫除盲点:教你理解位运算符。
方法一: 暴力破解
暴力破解是指我们使用双层for循环去解题。
我们第一层for循环去判断num的每一位是否为1,1有1的逻辑,0有0的逻辑。
第二层for循环就是去记录从1开始的,连续为1的数量。
这种方式的缺点在于,中间的逻辑很有可能会写错,反复检查会很麻烦。
具体实现看代码:
class Solution {
public:
int reverseBits(int num) {
bool flag = true; //标准位,类似与开关,第一次出现0,变成false,第二次出现0,变成true
int maxLength = 0; //记录最大长度
int count = 0;//记录1的数量
for(int i = 0; i < 32; ++i){
bool bit = num & (1<<i);
cout<<bit<<",";
if(bit == 1){//为1的逻辑
flag = true;
count = 0;
for(int j = i; j < 32; ++j){
bool bit_2 = num & (1<<j);
if(bit_2 && flag){
count+=1;
if(count > maxLength) maxLength = count;
}else if(bit_2 == 0 && flag){
count += 1;
if(count > maxLength) maxLength = count;
flag = false;
}else if(bit_2 == 1 && !flag){
count += 1;
if(count > maxLength) maxLength = count;
}else break;
}
}
if(bit == 0){
num |= (1<<i);
count = 0;
for(int j = i; j < 32; ++j){
bool bit_2 = num & (1<<j);
if(bit_2 == 1 ){
count += 1;
if(count > maxLength) maxLength = count;
}else if(bit_2 == 0){
num &= ~(1<<i);
break;
}
}
}
}
return maxLength;
}
};
复杂度分析
时间复杂度:O(n!) ,n第一开始是32,然后会随着i的增大而减小。
空间复杂度:O(1),我们没有申请额外的数据结构去存储数据。
方法二:使用贪心算法的思想去解题
贪心算法的思想是每一步选择当前状态下最优的决策,并不考虑之后的结果,以期达到全局最优解的算法思想。
在这道题中我们一共要设置三个变量,small,big,maxLength。
当遇到0时
,big 会等于 small 之前的状态 + 1,然后small会将自己置为0。
当遇到1时
,big和small都会加1。
maxLength
会不断比较自己与big的大小,并永远保持自己是最大的。最后返回maxLength。
具体代码如下:
class Solution {
public:
int reverseBits(int num) {
int small = 0; int big = 0; int maxLength = 0;
for(int i = 0; i < 32; ++i){
if(num & (1<<i) ){ //判断这一位是否为0
++small;
++big;
}else{
big = small + 1;
small = 0;
}
maxLength = max(big,maxLength);
}
return maxLength;
}
};
总结
这道题对我来说,确实也不算是一道难题,但也没那么简单。如果我会贪心思想了话,这道题或许会更加的简单。后序,我会更新双指针与动态规划的做法。