【每日算法0303】 位运算(简单)

96 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23天,点击查看活动详情

题目

剑指 Offer 15. 二进制中1的个数

编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为 汉明重量).)。

示例:

输入:n = 11 (控制台输入 00000000000000000000000000001011)
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

分析

本题考查的是二进制中的运算——&

  • 1 & 0 = 0
  • 1 & 1 = 1
  • 0 & 0 = 0

实现

var hammingWeight = function(n) {
    let count = 0
    
    while(n) {
        n = n & (n - 1)
        count ++
    }
​
    return count
};

题目

剑指 Offer 65. 不用加减乘除做加法

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

示例:

输入: a = 1, b = 1
输出: 2

分析

预备知识

有符号整数通常用补码来表示和存储,补码具有如下特征:

  • 正整数的补码与原码相同;负整数的补码为其原码除符号位外的所有位取反后加 1
  • 可以将减法运算转化为补码的加法运算来实现。
  • 符号位与数值位可以一起参与运算。

利用异或运算的特性^

异或:相同为0,相异为1

  • 异或可以模拟两数相加的结果,只是不包含进位
  • 注意,这是不考虑进位的结果。现在我们需要处理进位。我们可以使用位运算中的“与”和“移位”操作来实现。具体来说,我们可以计算出哪些位需要进位,并将这些进位向左移动一位,然后再加回到不考虑进位的结果中。这个过程可以一直重复,直到不再有进位。

实现

var add = function(a, b) {
    while(b){
        // 进位,二进制向左移动1位
        const c = (a & b) << 1
        // ab做或运算,不含进位的运算
        a = a ^ b
        // 将进位之后的结果赋值给 b
        b = c
    }
    return a
};