当前位置: 首页 > news >正文

面试经典150题——位运算

文章目录

  • 1、二进制求和
    • 1.1 题目链接
    • 1.2 题目描述
    • 1.3 解题代码
    • 1.4 解题思路
  • 2、颠倒二进制位
    • 2.1 题目链接
    • 2.2 题目描述
    • 2.3 解题代码
    • 2.4 解题思路
  • 3、位1的个数
    • 3.1 题目链接
    • 3.2 题目描述
    • 3.3 解题代码
    • 3.4 解题思路
  • 4、只出现一次的数字
    • 4.1 题目链接
    • 4.2 题目描述
    • 4.3 解题代码
    • 4.4 解题思路
  • 5、只出现一次的数字 II
    • 5.1 题目链接
    • 5.2 题目描述
    • 5.3 解题代码
    • 5.4 解题思路
  • 6、数字范围按位与
    • 6.1 题目链接
    • 6.2 题目描述
    • 6.3 解题代码
    • 6.4 解题思路


1、二进制求和

1.1 题目链接

点击跳转到题目位置

1.2 题目描述

给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。

提示:

  • 1 <= a.length, b.length <= 104
  • a 和 b 仅由字符 ‘0’ 或 ‘1’ 组成
  • 字符串如果不是 “0” ,就不含前导零

1.3 解题代码

class Solution {
    public String addBinary(String a, String b) {
        int m = a.length();
        int n = b.length();
        int i = m - 1;
        int j = n - 1;
        StringBuffer sb = new StringBuffer();
        int carry = 0;
        while(i >= 0 && j >=0){
            int num1 = a.charAt(i) - '0';
            int num2 = b.charAt(j) - '0';
            int num = (num1 + num2 + carry) % 2;
            carry = (num1 + num2 + carry) / 2;
            sb.append(num);
            --i;
            --j;
        }
        while(i >= 0){
            int num1 = a.charAt(i) - '0';
            int num = (num1 + carry) % 2;
            carry = (num1 + carry) / 2;
            sb.append(num);
            --i;
        }
        while(j >= 0){
            int num2 = b.charAt(j) - '0';
            int num = (num2 + carry) % 2;
            carry = (num2 + carry) / 2;
            sb.append(num);
            --j;
        }
        if(carry == 1){
            sb.append('1');
        }
        sb.reverse();
    return sb.toString();
    }
}

1.4 解题思路

  1. 二进制加法,采用模拟的思路,逐位相加,考虑进位即可。

2、颠倒二进制位

2.1 题目链接

点击跳转到题目位置

2.2 题目描述

颠倒给定的 32 位无符号整数的二进制位。

提示:

  • 请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
  • 在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数 -1073741825。

提示:

  • 输入是一个长度为 32 的二进制字符串

2.3 解题代码

public class Solution {
    // you need treat n as an unsigned value
    public int reverseBits(int n) {
        int res = 0;
        for(int i = 0; i < 32; ++i){
            res += (((n >> i) & 1) << (31 - i));
        }
        return res;
    }
}

2.4 解题思路

  1. 使用位运算直接反转,比如第0位的放置到第31位上去。

3、位1的个数

3.1 题目链接

点击跳转到题目位置

3.2 题目描述

给定一个正整数 n,编写一个函数,获取一个正整数的二进制形式并返回其二进制表达式中设置位(set bit 指在某数的二进制表示中值为 1 的二进制位)的个数(也被称为汉明重量)。

提示:

  • 1 <= n <= 231 - 1

3.3 解题代码

class Solution {
    public int hammingWeight(int n) {
        int res = 0;
        while(n > 0){
            n &= (n - 1);
            res++;
        }
        return res;
    }
}

3.4 解题思路

  1. 公式化题目,每次用n 与 n - 1做位运算,则能去除掉最低位的1.

4、只出现一次的数字

4.1 题目链接

点击跳转到题目位置

4.2 题目描述

给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。

提示:

  • 1 <= nums.length <= 3 * 104
  • -3 * 104 <= nums[i] <= 3 * 104
  • 除了某个元素只出现一次以外,其余每个元素均出现两次。

4.3 解题代码

class Solution {
    public int singleNumber(int[] nums) {
        int res = 0;
        for(int i = 0; i < nums.length; ++i){
            res ^= nums[i];
        }
        return res;
    }
}

4.4 解题思路

  1. 亦或运算解决问题。

5、只出现一次的数字 II

5.1 题目链接

点击跳转到题目位置

5.2 题目描述

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。

提示:

  • 1 <= nums.length <= 3 * 104
  • -231 <= nums[i] <= 231 - 1
  • nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次。

5.3 解题代码

class Solution {
    public int singleNumber(int[] nums) {
        int res = 0;
        for(int i = 0; i < 32; ++i){
            int ans = 0;
            for(int j = 0; j < nums.length; ++j){
                ans += (nums[j] >> i) & 1;
            }
            ans %= 3;
            if(ans > 0){
                res ^= (1 << i);
            }
        }
        return res;
    }
}

5.4 解题思路

  1. 使用位运算,计算所有的数在某一位的1的个数,如果是3的倍数,则那个只出现一次的数字在该为为0,否则的话在该位为1。

6、数字范围按位与

6.1 题目链接

点击跳转到题目位置

6.2 题目描述

给你两个整数 left 和 right ,表示区间 [left, right] ,返回此区间内所有数字 按位与 的结果(包含 left 、right 端点)。

提示:

  • 0 <= left <= right <= 231 - 1

6.3 解题代码

class Solution {
    public int rangeBitwiseAnd(int left, int right) {
        int shift = 0;
        while(left < right){
            left >>= 1;
            right >>= 1;
            ++shift;
        }
        return left << shift;
    }
}

6.4 解题思路

  1. 寻找left和right的二进制位的相等前缀即可。

相关文章:

  • 本地部署DeepSeek集成VSCode创建自己的AI助手
  • 国内 网络安全沙箱
  • IC-Portrait:打造逼真个性化肖像的新纪元!
  • 什么是AI Agent、Chat、RAG、MoE
  • http 模块
  • 网络安全协议之比较(SSH、PKI、SET、SSL)
  • 宏基传奇swift edge偶尔开机BIOS重置
  • kafka了解-笔记
  • 【React】组件通信
  • vsftpd 配置项说明
  • AI 如何改变职场:从增强到重塑工作的未来
  • C++基础 | 线程`std::thread`
  • VoIP之音视频会议中的混音技术
  • LeetCode 1552.两球之间的磁力:二分查找
  • Humanoid Robot Price Break 人形机器人价格突破
  • NO.14十六届蓝桥杯备战|switch语句|break|default|2道练习(C++)
  • 基于LSTM+前向均值滤波后处理的癫痫发作检测(包含数据集)
  • C++ 设计模式-装饰器模式
  • 第四篇:放大电路的“子弹时间”——车载音频与传感器信号链设计
  • oppo,康冠科技25届春招内推
  • 陕西籍青年作家卜文哲爬山时发生意外离世,终年28岁
  • 这款小孩子最爱的饮料,害处竟大到不敢想象
  • 这个东西每道菜里都有,却可能让你得一身病,做好这些能避免
  • 再囤三个月库存!美国客户抢付尾款,外贸企业发货订单排到7月
  • 交通运输局男子与两名女子办婚礼?官方通报:未登记结婚,开除该男子
  • 上海文化馆服务宣传周启动,为市民提供近2000项活动