《位运算技巧以及Leetcode的一些位运算题目》

目录

  • 技巧
  • 练习位运算
        • [461. 汉明距离](https://leetcode-cn.com/problems/hamming-distance/)
        • [190. 颠倒二进制位](https://leetcode-cn.com/problems/reverse-bits/)
        • [136. 只出现一次的数字](https://leetcode-cn.com/problems/single-number/)
        • [260. 只出现一次的数字 III](https://leetcode-cn.com/problems/single-number-iii/)
        • [268. 丢失的数字](https://leetcode-cn.com/problems/missing-number/)
        • [693. 交替位二进制数](https://leetcode-cn.com/problems/binary-number-with-alternating-bits/)
        • [476. 数字的补数](https://leetcode-cn.com/problems/number-complement/)
  • 练习二进制思想
        • [342. 4的幂](https://leetcode-cn.com/problems/power-of-four/)
        • [318. 最大单词长度乘积](https://leetcode-cn.com/problems/maximum-product-of-word-lengths/)
        • [338. 比特位计数](https://leetcode-cn.com/problems/counting-bits/)
  • 一些补充
        • 剑指 Offer 56 - I. 数组中数字出现的次数

技巧

位运算的一些基础技巧

 x ^ 0... = xx ^ 1... = ~xx ^ x = 0x & 0... = 0x & 1... = xx & x = xx | 0... = xx | 1... = 1...x | x = x

进阶技巧

n & (n-1) 可以去除n的位级表示中最低的一位:
如 n = 11110100 , n - 1 = 11110011
n & (n-1) = 11110000
n & (-n)  可以得到n的位级表示中最低的那一位:
如 n = 11110100 , 取负:-n = 00001100
n & (-n) = 00000100

练习位运算

461. 汉明距离

先异或运算,然后统计1个数:

class Solution {
public:int hammingDistance(int x, int y) {int XOR_result = x ^ y;int result = 0;while(XOR_result != 0){result += (XOR_result & 1);XOR_result = XOR_result >> 1;}return result;}
};

190. 颠倒二进制位

result不断左移,最低位加上n的最低位,n不断右移。

class Solution {
public:uint32_t reverseBits(uint32_t n) {uint32_t result = 0;for(int i = 0; i < 32; i++){result = result << 1;result += n & 1;n = n >> 1;}return result;}
};

136. 只出现一次的数字

思路一:哈希先扫一遍,然后再扫一遍,找到second为1的it。

class Solution {
public:int singleNumber(vector<int>& nums) {unordered_map<int,int> umap;int result = 0;for(int i = 0; i < nums.size(); i++){umap[nums[i]]++;}for(auto it : umap){if(it.second == 1) return it.first;}return 0;}
};

思路二:利用 x ∧ x = 0 和 x ∧ 0 = x 的特点,将数组内所有的数字进行按位异或。出现两次
的所有数字按位异或的结果是 0,0 与出现一次的数字异或可以得到这个数字本身。神仙思路!

class Solution {
public:int singleNumber(vector<int>& nums) {int result = 0;for(int num : nums)result = num ^ result;return result;}
};

260. 只出现一次的数字 III

这次是有两个不同的元素,那么用位运算如何做呢?
觉得这个题解写的很好,浅显易懂。
某题解
编程时注意一下细节:
1、&的优先级比==低,所以需要加括号
2、用int作为res会报错,需要用long

class Solution {
public:vector<int> singleNumber(vector<int>& nums) {long res = 0;for(int i = 0; i < nums.size(); i++){res = res ^ nums[i];}//此时res = a ^ b;//找出1的位级表示中最低的那一位,代表着a与b在这一位是不一样的,假设a在这一位为0,b在这一位为0res = res & (-res);int a = 0;int b = 0;for(int i = 0; i < nums.size(); i++){if((nums[i] & res) == 0)  //不可能b,而且除了a其他符合要求的都是重复的a = nums[i] ^ a;else b = nums[i] ^ b;}return {a,b};}
};

268. 丢失的数字

XOR原理:x ^ x = 0; 0 ^ y =y;
两个相同的数字XOR之后为0,如果这个数字只出现了一次,那么XOR之后还是本身。这一题本质上和上一题是一样的。
一些细节,看注释

class Solution {
public:int missingNumber(vector<int>& nums) {int n = nums.size();int result = n;             //因为for循环中i不能为n,而我们必须遍历[0,n],所以初值设置为nfor(int i = 0; i < n; i++)  //遍历nums数组,其丢失数在nums[] + [0..n]中只出现了一次{result = result ^ i ^ nums[i];}return result;}
};

693. 交替位二进制数

class Solution {
public:bool hasAlternatingBits(int n) {int prev_tail = n & 1;while(n){int now_tail = (n >> 1) & 1;if(now_tail == prev_tail) return false;prev_tail = now_tail;n = n >> 1;}return true;}
};

476. 数字的补数

思路一:一个一个来,注意倒序。

class Solution {
public:int findComplement(int n) {int result = 0;vector<int> res;while(n){res.emplace_back(!(n & 1));n = n >> 1;}for(int i = res.size() - 1; i >=0; i--){result = (result << 1) | res[i];}return result;}
};

当然也可以使用栈来做,思路一样的:

class Solution {
public:int findComplement(int n) {int result = 0;stack<int> res;while(n){res.push(!(n&1));n >>= 1;}while(!res.empty()){result = (result << 1) | res.top();res.pop();}return result;}
};

思路二:使用异或
举例:
5的二进制是:0101,7的二进制是: 0111,它们的抑或为:0010,去掉前导零位即为取反。
再来一个例子,假设a为1110 0101,b为1111 1111,a^b = 0001 1010是a的取反。也就是说二进制位数与num相同,且全为1的数tmp与num的抑或即为所求。

class Solution {
public:int findComplement(int n) {int tmp=0;int tmp_n = n;while(n){tmp = (tmp << 1) | 1;n >>= 1;}return tmp ^ tmp_n;}
};

练习二进制思想

342. 4的幂

先考虑2的次方:
如果n为2的整数次方,那么它的二进制一定是0...1...0的形式;那么n-1的二进制应该是0..011...1的形势。这两个数按位求与的结果一定为0。
如果n为4的整数次方,它一定为2的偶数幂。所以4的幂与二进制数(1010101010…10)相与会得到0.
int 为32位,每4位1010对应16进制a,所以应该为0xaaaaaaaa;
注意&与==的优先级。

class Solution {
public:bool isPowerOfFour(int n) {return ( n > 0 && (n & n-1) == 0 && (n & 0xaaaaaaaa) == 0);}
};

318. 最大单词长度乘积

怎样快速判断两个字母串是否含有重复数字呢?可以为每个字母串建立一个长度为26的二进制数字,每个位置表示是否存在该字母。如果两个字母串含有重复数字,那它们的二进制表示的按位与不为0。同时,我们可以建立一个哈希表来存储字母串(在数组的位置)到二进制数字的映射关系,方便查找调用。

class Solution {
public:int maxProduct(vector<string>& words) {unordered_map<int,int> hashmap;             //使用哈希表来存储(位掩码 -> 单词长度)int ans = 0;for(auto word : words)                      //遍历每个string{int mask = 0;                           //位掩码int size = word.size();                 //单词长度for(auto c : word)                      //encode位掩码mask = mask | (1 << (c-'a'));hashmap[mask] = max(hashmap[mask],size);//如果掩码相同,存储更长的字符串(说明有些字符重复)//对比当前单词与之前的所有单词,无重复字符,且长度乘积大于ans则更新ansfor(auto it : hashmap){if((mask & it.first)== 0)            //如果无重复字符{ans = max(ans,size*it.second);}}}return ans;}
};

338. 比特位计数

利用dp+位运算。
定义一个数组dp,dp[i]表示数字i的二进制含有1的个数。
对于第i个数字,如果它二进制的最后一位为1,那么它含有1的个数则为dp[i] = dp[i-1]+1;
如果它二进制的最后一位为0,那么它含有1的个数和其右移结果相同,即dp[i] = dp[i>>1]

class Solution {
public:vector<int> countBits(int num) {vector<int> dp(num+1,0);for(int i = 1; i <= num; i++){if((i & 1) == 1)dp[i] = dp[i-1] + 1;else dp[i] = dp[i>>1];}return dp;}
};

一些补充

2021.7.4

剑指 Offer 56 - I. 数组中数字出现的次数

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

示例 1:
输入:nums = [4,1,4,6]
输出:[1,6][6,1]
示例 2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10][10,2]
限制:
2 <= nums.length <= 10000

两个只出现依次的数字位x,y
x和y二进制至少有一位不同,根据此位可以将nums划分成分别包含x和y的两个子数组。
分别对两个子数组遍历执行异或操作,可以得到两个只出现一次的数字x,y。
1、遍历nums数组执行异或,得到结果 x^y
2、x^y某二进制位为1,则x和y的此二进制位一定不同。
初始化一个辅助变量m = 1,从右向左循环判断,可以得到x^y的首位1,记录在m中。
3、拆分nums为两个子数组
4、分别遍历两个子数组执行异或
for(num : nums)
if(num & m == 1) x ^= num;
else y ^= num;
return x,y;
最终代码:

vector<int> singleNumbers(vector<int>& nums)
{int ret = 0;for(int n : nums)ret ^= n;			// x^yint div = 1;while((ret & div) == 0)div <= 1;int x = 0, y = 0;for(int n : nums){if(div & n == 0)a ^= n;else b ^= n;}return vector<int> {x,y};
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377080.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux读取配置文件(C语言版)

一个通用的linux系统中C语言版读取配置文件的函数。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <errno.h>#define KEYVALLEN 100/* 删除左边的空格 */ char * l_trim(char * szOutput, con…

java 范围搜寻要怎么弄_搜索范围

java 范围搜寻要怎么弄Problem statement: 问题陈述&#xff1a; Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value. 给定一个以升序排列的整数nums数组&#xff0c;请找到给定目标值的开始和结束…

boa + ajax + cgi ajax请求cgi

最近公司要做一个通讯管理机,然后需要和另外一个同事一起做,我们需要用到boaAjaxCGI,以前没试过与CGI交互,一开始发现问题挺大的,用ajax请求cgi,总是不返回数据,又或者请求回来的是cgi的源码,后来发现,通过本地IIS或者直接打开html页面请求的,返回来的都是cgi的源码或者返回失败…

《DBNotes:single_table访问方法、MRR多范围读取优化、索引合并》

目录single_table访问方法constrefref_or_nullrangeindexallMRR多范围读取优化索引合并intersectionunionsort-unionsingle_table访问方法 const 在主键列或者unique二级索引与一个常数进行等值比较时才有效。 如果主键或者unique二级索引的索引列由多个列构成&#xff0c;则…

怎样通过命令管理Windows7桌面防火墙

&#xff08;1&#xff09;启用桌面防火墙netsh advfirewall set allprofiles state on&#xff08;2&#xff09;设置默认输入和输出策略netsh advfirewall set allprofiles firewallpolicy allowinbound,allowoutbound以上是设置为允许&#xff0c;如果设置为拒绝使用blockin…

ruby推送示例_Ruby for循环示例

ruby推送示例for循环 (The for loop) In programming, for loop is a kind of iteration statement which allows the block to be iterated repeatedly as long as the specified condition is not met or a specific number of times that the programmer knows beforehand. …

《DBNotes: Buffer Pool对于缓冲页的链表式管理》

目录Buffer Pool回顾Buffer Pool内部组成freelistflushlistLRU链表管理以及改进Buffer Pool回顾 我们知道针对数据库的增删改删操作都是在Buffer Pool中完成的&#xff0c;一条sql的执行步骤可以认为是这样的&#xff1a; 1、innodb存储引擎首先在缓冲池中查询有没有对应的数据…

一个延时调用问题

如果用下面第1行的写法&#xff0c;调用 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:selector(removeFromSuperview) object:nil]; 可以生效 如果用下面第3行的写法&#xff0c;调用 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:…

onclicklistener 方法使用汇总

相信很多像我一样的新手学习ANDROID开发会遇到这个问题&#xff0c;通过这几天的归类和总结&#xff0c;将我的理解写在下面&#xff0c;欢迎大家一起前来讨论&#xff1a; 以按钮BUTTON的监听事件为例&#xff0c;以下的监听实现都是等价的&#xff1a; 1.使用接口继承按钮监听…

《源码分析转载收藏向—数据库内核月报》

月报原地址&#xff1a; 数据库内核月报 现在记录一下&#xff0c;我可能需要参考的几篇文章吧&#xff0c;不然以后还得找&#xff1a; MySQL 代码阅读 MYSQL开源软件源码阅读小技巧 MySQL 源码分析 聚合函数&#xff08;Aggregate Function&#xff09;的实现过程 MySQL …

vim中的jk为什么是上下_JK的完整形式是什么?

vim中的jk为什么是上下JK&#xff1a;开玩笑 (JK: Just Kidding) JK is an abbreviation of "Just Kidding". JK是“ Just Kidding”的缩写 。 It is an expression, which is commonly used in messaging or chatting on social media networking sites like Faceb…

百度归来的学长做报告

今天下午下课到现在才总算闲下来&#xff0c;本来计划这个时间应该是读英语&#xff0c;做英语模拟题的时间&#xff0c;但是&#xff0c;我不得不写点什么来记录下刚才的事——在百度实习并且签下工作的学长做报告。 原本认为每个人的成功&#xff08;请允许我目前的眼光签个好…

转:Google论文之三----MapReduce

文章来自于&#xff1a;http://www.cnblogs.com/geekma/p/3139823.html MapReduce&#xff1a;大型集群上的简单数据处理 摘要 MapReduce是一个设计模型&#xff0c;也是一个处理和产生海量数据的一个相关实现。用户指定一个用于处理一个键值&#xff08;key-value&#xff09;…

合约 cd 模式_CD的完整形式是什么?

合约 cd 模式CD&#xff1a;光盘 (CD: Compact Disc) CD is an abbreviation of "Compact Disc". CD是“ Compact Disc”的缩写 。 It is a digital optical disc originally developed to store the audio of recordings in the format of a data file used as a p…

《DBNotes:Join算法的前世今生》

目录NestLoopJoin算法Simple Nested-Loop JoinIndex Nested-Loop JoinBlock Nested-Loop JoinBatched Key AccessHash Join算法In-Memory Join(CHJ)On-Disk Hash Join参考链接在8.0.18之前&#xff0c;MySQL只支持NestLoopJoin算法&#xff0c;最简单的就是Simple NestLoop Joi…

如何解决迅雷插件导致IE10崩溃的问题

Windows 8里面带的IE10酷不酷&#xff1f;沉浸式界面果然不同凡响&#xff0c;IE10让人几乎认不出来了&#xff01;这是微软的浏览器么&#xff1f;上面这张图是Windows8下Metro UI的新界面IE10&#xff0c;不过当我们切换回传统桌面的时候&#xff0c;也有IE10的经典版的。好吧…

UNITY3D与iOS交互解决方案

原地址&#xff1a;http://bbs.18183.com/thread-456979-1-1.html 本帖最后由 啊,将进酒 于 2014-2-27 11:17 编辑 “授人以鱼&#xff0c;不如授人以渔”&#xff0c;以UNITY3D调用iOS版的91SDK为例&#xff0c;利用C# / C / OBJ-C交互原理,本文将详细介绍UNITY3D与iOS之间交互…

c:if equal_C ++中的std :: equal()

c:if equalequal()作为STL函数 (equal() as a STL function) Syntax: 句法&#xff1a; bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);Where, 哪里&#xff0c; InputIterator1 first iterator to start of the first sequence range I…

《DBNotes:Buffer Pool刷脏页细节以及改进》

本笔记知识沿用之前DBNotes: Buffer Pool对于缓冲页的链表式管理的部分知识 目录获取一个空闲页的源码逻辑Page_Cleaner_ThreadLRU_Manager_ThreadHazard Pointer作为驱逐算法改进参考获取一个空闲页的源码逻辑 任何一个读写请求都需要从Buffer pool来获取所需页面。如果需要的…

WordPress删除数据中标题重复文章的方法

一种是删除重复的方法是&#xff1a;使用插件,大家可以去官网上下载 二种删除重复的方法是&#xff1a;登录数据库&#xff0c;使用sql语句删除&#xff0c;具体的语句为如下代码&#xff1a; CREATE TABLE my_tmp AS SELECT MIN(ID) AS col1 FROM wp_posts GROUP BY post_titl…