牛客网剑指offer-位运算(java实现)

一、JZ65 不用加减乘除做加法(简单)

1、位运算

public class Solution {
    public int Add(int num1,int num2) {
        // add表示进位值
        int add = num2;         
        // sum表示总和       
        int sum = num1;                
        // 当不再有进位的时候终止循环
        while(add != 0) {              
            // 将每轮的无进位和与进位值做异或求和
            int temp = sum ^ add;      
            // 进位值是用与运算产生的
            add = (sum & add) << 1;    
            // 更新sum为新的和
            sum = temp;                
        }
        return sum;
    }
}

二、JZ15 二进制中1的个数(简单)

1、我们都只知道数字1与数字相位与运算,其实只是最后一位为1就是1,最后一位为0就是0,这样我们只需要将数字1移位运算,就可以遍历二进制的每一位,再去做位与运算,结果为1的就是二进制中为1的。

public class Solution {
    public int NumberOf1(int n) {
        int res = 0;
        //遍历32位
        for(int i = 0; i < 32; i++){
            //按位比较
            if((n & (1 << i)) != 0)   
                res++;
        }
        return res;
    }
}

三、JZ16 数值的整数次方(中等)

1、直接运算

public class Solution {
    public double Power(double base, int exponent) {
        //处理负数次方
        if(exponent < 0){
            base = 1 / base;
            exponent = -exponent;
        }
        double res = 1.0;
        //累乘
        for(int i = 0; i < exponent; i++)
            res *= base;
        return res;
  }
}

2、快速幂

public class Solution {
    //快速幂
    private double Pow(double x, int y){ 
        double res = 1;
        while(y != 0){
            //可以再往上乘一个
            if((y & 1) != 0) 
                res *= x;
            //叠加
            x *= x; 
            //减少乘次数
            y = y >> 1; 
        }
        return res;
    }
    public double Power(double base, int exponent) {
        //处理负数次方
        if(exponent < 0){
            base = 1 / base;
            exponent = -exponent;
        }
        return Pow(base, exponent);
  }
}

四、JZ56 数组中只出现一次的两个数字(中等)

1、遍历逐个判断

import java.util.*;
public class Solution {
    /**
     * @param array int整型一维数组 
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] array) {
        // write code here
        Arrays.sort(array);
        int [] result = new int[2];
        int o = 0;
        for(int i = 0;i < array.length;i++) {
            if(i == 0 && array[i] != array[i+1]) {
                result[o] = array[i];
                o++;
                continue;
            }
            if(i> 0 && (i < array.length - 1) && array[i] != array[i-1] && array[i] != array[i+1]){
                result[o] = array[i];
                o++;
                continue;
            }
            if(i == array.length -1 && array[i] != array[i-1]) {
                 result[o] = array[i];
                 o++;
            }
        }
        return result;
    }
}

2、找到分组规则,再进行异或遍历

public int[] FindNumsAppearOnce (int[] array) {

        // 先将全部数进行异或运算,得出最终结果
        int tmp = 0;
        for(int num: array){
            tmp ^= num;
        }

        // 找到那个可以充当分组去进行与运算的数
        // 从最低位开始找起
        int mask = 1;
        while((tmp&mask) == 0){
            mask <<= 1;
        }

        // 进行分组,分成两组,转换为两组 求出现一次的数字 去求
        int a = 0;
        int b = 0;
        for(int num:array){
            if((num&mask) == 0){
                a ^= num;
            }else{
                b ^= num;
            }
        }
        // 因为题目要求小的数放前面,所以这一做个判断
        if(a > b){
            int c = a;
            a = b;
            b = c;
        }
        return new int[]{a,b};
    }

五、JZ64 求1+2+3+...+n(中等)

1、递归

public class Solution {
    public int Sum_Solution(int n) {
        //通过与运算判断n是否为正数,以结束递归
        boolean flag = (n > 1) && ((n += Sum_Solution(n - 1)) > 0); 
        return n;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值