位运算

基础知识

原码、反码和补码

二进制有三种不同的表示形式:原码、反码和补码,计算机内部使用补码来表示

原码:就是其二进制表示,(其中第一位为符号位)

反码:正数的反码就是原码,负数的反码是符号位不变,其余位取反。

补码:正数的补码就是原码,负数的补码是反码+1

符号位:最高位为符号位,0表示正数,1表示负数,在位运算中符号位也参与位运算

位运算操作

1.按位非操作

整数的二进制每一位都取反(0变成1,1变成0)

00 00 01 01 -> 5
~
11 11 10 10 -> -6  (反码是11 11 10 01, 原码是10 00 01 10,因此是-6)

2.按位与操作

只有二进制中两个对应位是1才为1

00 00 01 01 -> 5
&
00 00 01 10 -> 6
---
00 00 01 00 -> 4

3.按位或操作

二进制中有一个对应位是1就为1,全为0结果才为0

00 00 01 01 -> 5
|
00 00 01 10 -> 6
---
00 00 01 11 -> 7

4.按位异或操作

只有对应位不同结果为1,否则为0

00 00 01 01 -> 5
^
00 00 01 10 -> 6
---
00 00 00 11 -> 3

异或的操作满足交换律和结合律,即:

A^B = B^A

ABC = A(BC)

A^A = 0

A^0 = A

ABA = AAB = 0^B = B

5.按位左移操作

num << inum的二进制表示向左移动i位,右边补0得到的值,左移1位表示十进制的数值加倍。

00 00 10 11 -> 11
11 << 3
01 01 10 00 -> 88

6.按位右移操作

num >> inum的二进制表示向右移动i位得到的值

00 00 10 11 -> 11
11 >> 3
00 00 00 10 -> 2

题目解析

只出现一次的数字

1.题目描述

题目链接

2.解析思路及代码

对每个数进行异或即可得到答案,因为任何数异或自己等于0,题目中说了只有一个数出现一次,其他都出现两次,因此出现两次的数字异或结果都为0,0异或只出现一次的数等于只出现一次的数,时间复杂度为O(n)

 public int singleNumber(int[] nums) {int res = 0;for (int i = 0; i < nums.length; i ++ ) {res = res ^ nums[i];}return res;}
class Solution:def singleNumber(self, nums: List[int]) -> int:res = 0for item in nums:res = res ^ itemreturn res

只出现一次的数字 III

1.题目描述

题目链接

2.解题思路及代码

思路:

  • 使用哈希表存储每个数字出现的次数,然后将出现次数为1的结果返回
  • 使用异或操作和与操作,假设出现一次的数字为x1、x2,首先将所有数异或,根据上一题可得最后的结果为x=x1⊕x2x = x1 \oplus x2x=x1⊕x2,然后取x的最后一个1,即使用x & -x,因为该位的结果为1,因此可以得出x1和x2的该位一定是不相同的,使用与运算可以将原数组所有数的该位分成两组,x1和x2一定不在同一组,那么每组都只会有一个出现一次的数,即可得到最后的结果。
 public int[] singleNumber(int[] nums) {if (nums.length < 2)    return new int[2];int res = 0;for (int num : nums) {res ^= num;}res = res & (-res);int num1 = 0, num2 = 0;for (int num : nums) {if ((res & num) == 0) {num1 ^= num;} else {num2 ^= num;}}return new int[]{num1, num2};}
class Solution:def singleNumber(self, nums: List[int]) -> List[int]:if len(nums) < 2:return []res = 0for num in nums:res ^= numres = res & (-res)num1, num2 = 0, 0for num in nums:if res & num == 0:num1 ^= numelse:num2 ^= numreturn [num1, num2]

只出现一次的数字 II

1.题目描述

题目链接

2.解题思路及代码

  • 使用哈希表映射每个数字的出现次数,然后找出只出现一次的元素
  • 获取答案的每一位上的数字,因为其他数都出现三次,因此答案的每一位数字等于所有数字出现的结果和模3,注意如果目标语言不区分有符号数和无符号数,最高位需要特判。
 public int singleNumber(int[] nums) {int res = 0;for (int i = 0; i < 32; i ++ ) {int total = 0;for (int num : nums) {total += ((num >> i) & 1);}if ((total % 3) == 1) {res |= (1 << i);}}return res;}
class Solution:def singleNumber(self, nums: List[int]) -> int:res = 0for i in range(32):total = sum((num >> i) & 1 for num in nums)if total % 3:if i == 31:res -= (1 << i)else:res |= (1 << i)return res

2 的幂

1.题目描述

题目链接

2.解题思路及代码

  • 使用n & (n - 1)可以移除n的最低位,判断该结果是否为0即可
  • 使用n & (-n)可以取出n的最后一个1,判断该结果是否与n相等即可
 public boolean isPowerOfTwo(int n) {return n > 0 && ((n & (n - 1)) == 0);}
class Solution:def isPowerOfTwo(self, n: int) -> bool:return n > 0 and (n == (n & (-n)))

子集

1.题目描述

题目链接

2.解题思路及代码

  • 迭代得到结果,数组中出现的每一个结果都可以用二进制对应的位数表示,假设数组有3个元素,那么100表示第一个元素出现,第二个元素不出现,第三个元素不出现,最终的二进制最大值为111。
  • 递归求解,对于数组的每一个位置的值,可以选择包含或不包含
 public List<List<Integer>> subsets(int[] nums) {List<Integer> tmp = new ArrayList<>();List<List<Integer>> ans = new ArrayList<>();for (int i = 0; i < (1 << nums.length); i ++ ) {tmp.clear();for (int j = 0; j < nums.length; j ++ ) {if ((i & (1 << j)) != 0) {tmp.add(nums[j]);}}// 注意这里必须重新初始化一个List,否则ans的最后结果都会指向同一个值ans.add(new ArrayList<Integer>(tmp));}return ans;}class Solution {List<Integer> tmp = new ArrayList<>();List<List<Integer>> ans = new ArrayList<>();public List<List<Integer>> subsets(int[] nums) {dfs(0, nums);return ans;}public void dfs(int cur, int[] nums) {if (cur == nums.length) {ans.add(new ArrayList<>(tmp));return ;}// 不选择该位dfs(cur + 1, nums);// 选择该位tmp.add(nums[cur]);dfs(cur + 1, nums);tmp.remove(tmp.size() - 1);}
}
class Solution:def subsets(self, nums: List[int]) -> List[List[int]]:res = [[]]for i in nums:# 在每一个现有的结果前加上当前数字res = res + [[i] + num for num in res]return res

Leetcode刷题06-位运算相关推荐

  1. LeetCode刷题:位运算(找不同 和 只出现一次的数字)

    1.常见的位运算 按位与&:(1&1=1,1&0=0,0&1=0,0&0=0); 按位或 | : (1 | 1=1,1 | 0=1,0 | 1=1,0 | 0= ...

  2. 力扣刷题记录--位运算问题

    这里写目录标题 一.n&(n-1) 1. 求一个数的二进制表示中的1的个数 力扣 191. 位1的个数 AcWing 801. 二进制中1的个数 2. 判断一个数是否是2的方幂 二.n& ...

  3. C#LeetCode刷题-位运算

    位运算篇 # 题名 刷题 通过率 难度 78 子集 67.2% 中等 136 只出现一次的数字 C#LeetCode刷题之#136-只出现一次的数字(Single Number) 53.5% 简单 1 ...

  4. 第一届LeetCode刷题打卡赢现金活动开始啦,助力每一位想拿大厂offer的小伙伴!

    大家好,我是路飞!第一届leetcode(剑指Offer.LeetCode Top100)刷题打卡活动即将开始啦 (助力大厂Offer收割机)~ 活动形式: LeetCode刷题在自己的CSDN博客上 ...

  5. Leetcode刷题

    刷题 leetcode 1.两数之和 #哈希表 class Solution:def twoSum(self, nums: List[int], target: int) -> List[int ...

  6. Leetcode-How-What 力扣Leetcode刷题指南

    Leetcode-How-What 力扣Leetcode刷题指南 About the way how to use Leetcode wisely for preparing the intervie ...

  7. C#LeetCode刷题-程序员面试金典

    本文由 比特飞 原创发布,欢迎大家踊跃转载. 转载请注明本文地址:C#LeetCode刷题-程序员面试金典 | .Net中文网. C#LEETCODE刷题概述 概述 所有LeetCode程序员面试金典 ...

  8. C#LeetCode刷题-剑指Offer

    本文由 比特飞 原创发布,欢迎大家踊跃转载. 转载请注明本文地址:C#LeetCode刷题-剑指Offer | .Net中文网. C#LEETCODE刷题概述 概述 所有LeetCode剑指Offer ...

  9. C#LeetCode刷题-数学

    数学篇 # 题名 刷题 通过率 难度 2 两数相加 29.0% 中等 7 反转整数 C#LeetCode刷题之#7-反转整数(Reverse Integer) 28.6% 简单 8 字符串转整数 (a ...

  10. python基础刷题_数据结构与算法LeetCode刷题(Python)

    参考资料: 一.链表 1.  链表的必备知识要点(包括基础知识.刷题中使用的STL等知识) 2.  链表逆序(LeetCode 92 ,206. Reverse Linked List 1,2) 3. ...

最新文章

  1. 如何安装rabbitmq
  2. python ffmpeg 视频转图片 视频转音频 播放音频 多张图片+音频转视频 多个视频合成一个视频 改变视频播放速度
  3. SQL group by底层原理——本质是排序,可以利用索引事先排好序
  4. 阿里云分布式容器平台即将全面启动公测
  5. 第十节:基于MVC5+Unity+EF+Log4Net的基础结构搭建
  6. java 如何循环执行一个对象_Java基础:如何定义好一个方法和进行方法重载
  7. python进阶16多继承与Mixin
  8. 《校园封神榜》个人工作总结——第十天
  9. 快速列出所有字段_【小麦课堂】快速查询明细数据的操作
  10. 网站五万ip需要服务器,30万IP网站要用什么样的服务器?
  11. C++中一个类禁止继承好麻烦
  12. 计算机管理打印机服务,Windows下打印服务器的管理(一)
  13. mysql根据出生日期计算年龄并查询
  14. html 弹窗实现拖拽,原生js实现自由拖拽弹窗代码demo
  15. java项目远程调用别的项目接口
  16. 按行遍历和按列遍历哪一个更快一些?
  17. C语言函数递归—经典递归问题
  18. 淋巴细胞转化中PHP的作用,淋巴细胞转化试验范围|意义
  19. 究竟什么病毒轻而易举感染了全球8500万部手机?
  20. 程序员带你一步步分析AI如何玩Flappy Bird

热门文章

  1. 程序员成长之旅——C语言三子棋
  2. java vpa_使用VPA快速洞悉Java应用性能瓶颈
  3. 人人通服务器返回为空,沁教云人人通-操作手册教师版-V1.doc
  4. 为什么宝宝本来发高烧却手脚冰凉呢?
  5. Linux pwm_fan 风扇驱动
  6. NOIWC 2019 冬眠记【游记】
  7. 语文七年级计算机作文,我从电脑游戏中学到了语文初一作文
  8. 高职院校文学鉴赏教学中培养学生的主体性策略
  9. 360图片搜索API
  10. 心态和想法,是提高编程水平的关键