zoukankan      html  css  js  c++  java
  • 剑指offer-二进制中1的个数

    题目:二进制中1的个数

    题目描述:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

    思路:这个题比较有意思,平时碰到二进制的题还是蛮少的

    法1:直接将数n进行移位,从n 的二进制右面进行比较,先将n与1与一下,如果结果为1,则说明n的当前这一位为1,则计数器counts++,然后n右移一位,继续进行上述操作,直到n为0。上述做法对于正数是没问题的,但对于负数,其在右移时左边的符号位总是总动补1,导致程序会陷入死循环

    所以要用>>>是无视符号位的右移,而不是>>带符号位右移

    代码:

     1 public class Solution {
     2     public int NumberOf1(int n) {
     3         int counts=0;
     4        
     5             while(n!=0){
     6                 if((n&1)==1){counts++;}
     7                 n=n>>>1;         
     8         }
     9         return counts;
    10     }
    11 }

    法2:也可以不移整数n,反而去移1,每次让1左移一位去逐次的与n的各个位置进行比较

     1 public class Solution {
     2     public int NumberOf1(int n) {
     3         int counts=0;
     4         int flag=1;    
     5           while(flag!=0){
     6                 if((n&flag)!=0){counts++;}
     7                 flag=flag<<1;         
     8         }
     9         return counts;
    10     }
    11 }

    不过,这里注意这里的flag只有在刚开始等于1,左移一位后,flag=2(10),再左移就变成了4(100),当1进行了32次左移后,flag=0跳出while循环,因为int型最大是32位,另外在这只能是(n&flag)!=0,而不是(n&flag)==1,因为n&flag可能等于任何数,实质上就是两个数相与

    法3,学习一下与运算的最优解

     1 public class Solution {
     2     public int NumberOf1(int n) {
     3         int counts=0;     
     4           while(n!=0){
     5                counts++;
     6                n=n&(n-1);     
     7         }
     8         return counts;
     9     }
    10 }

    这个n=n&(n-1)其实也很好理解,相当于把二进制右端的位置,如果是1,则计数并将该位1清0,如果是0,则跳过该位了

    以n=1111为例,循环一次后,n=1110;循环2次后,n=1100;循环3次后,n=1000;循环4次后,n=0000,跳出循环了

    以n=1101为例,循环一次后,n=1100;循环2次后,n=1000;循环3次后,n=0000,跳出循环了

  • 相关阅读:
    在路上(转)
    我,机器
    梧桐道上
    傅盛:如何快慢“炼”金山?(转)
    [JS]笔记15之客户端存储cookie
    [JS]笔记14之事件委托
    [JS]笔记13之Date对象
    将博客搬至CSDN
    [JS]笔记12之事件机制--事件冒泡和捕获--事件监听--阻止事件传播
    [JS]笔记11之正则表达式
  • 原文地址:https://www.cnblogs.com/pathjh/p/9135546.html
Copyright © 2011-2022 走看看