剑指offer刷题:位运算和二进制

基础知识

1.移位运算

<< :  左移运算符,num << 1,相当于num乘以2

>> :  右移运算符,num >> 1,相当于num除以2

>>>:  无符号右移,忽略符号位,空位都以0补齐

一、二进制中1的个数

1.题目

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

2.思路

逐位和1进行与操作。如果返回1则计数cont加一。
逐位实现的思路: 每比较一次,该数进行无符号右移一次(n=n>>>1)

3.代码

public class Solution {
    public int NumberOf1(int n) {
        int cont = 0;
        while(n!=0){
            cont = cont +(n&1);     //比较当前末位是否为1
            n = n>>>1;              //无符号右移一次
        }
        return cont;
    }
}

二、不用加减乘除做加法

1.题目

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

2.思路

加法的实现原理(分为逐位和+进位和)

  1. 获取逐位相加的结果
  2. 获取进位的值
  3. 不断将这两个结果在此相加,直到没有进位(即代码中的num2为0)。

(1)对于十进制的加法

4. 首先不考虑进位,首先逐位相加,得到的结果与进位结果相加。
5. 不断迭代直到没有进位

对于12+19 = 31
12+19,逐位相加,
得到21,进位10,逐位相加,
31,进位0,得到结果。

(2)对于二进制的加法

  1. 两个数异或:相当于每一位相加,而不考虑进位
  2. 两个数相与,并左移一位:相当于求得进位
13+11 =;
13 的二进制      1 1 0 1       -----a        13
11 的二进制      1 0 1 1   	   -----b        11  

(a&b)<<1     	1 0 0 1 0      -----d        18
a^b  ->     	0 1 1 0        -----e         6

(d&e)<<1     	0 0 1 0 0     ------f         4
d^e      		1 0 1 0 0      -----g        20

(f&g)<<1 	    0 1 0 0 0     ------h         8
f^g     		1 0 0 0 0     ------i        16

(h&i)<<1  	    0 0 0 0 0     ------h         0   --------退出循环
h^i   		    1 1 0 0 0     ------i        24

3.代码

public class Solution {
        public int Add(int num1,int num2) {
		int sum = num1;//保证当num2为0时候返回num1
		int carry = 0;
		while(num2 != 0) {
			sum = num1 ^ num2;          //两个数异或:相当于每一位相加,而不考虑进位
			carry = (num1 & num2) << 1;//两个数相与,并左移一位:相当于求得进位
			num1 = sum;
			num2 = carry;
		} 
		return sum;
    }
}

4.拓展,用二进制来做减法

-n = ~n+1
然后a-b = a+(-b)即可。

三、求1+2+3+…+n

1.题目

求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

2.思路

  1. 不让用任何关键字。但是该求和问题的关键就是如何让求和过程停下来。即判断(n>0)。
  2. 所以要使用这个boolean量(n>0),可以用递归。
  3. (n>0) && ((sum+=Sum_Solution(n-1))>0)
1. 当n==0时,(n>0)&&((sum+=Sum_Solution(n-1))>0)只执行前面的判断,为false,然后直接返回02. 当n>0时,执行sum+=Sum_Solution(n-1),实现递归计算Sum_Solution(n)

3.代码

public class Solution {
    public int Sum_Solution(int n) {
        int sum = n;
        boolean temp = (n>0) && ((sum+=Sum_Solution(n-1))>0);
        return sum;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值