【LeetCode】421. Maximum XOR of Two Numbers in an Array 解题报告(Python & C++)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/description/
题目描述
Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 2^31.
Find the maximum result of ai XOR aj, where 0 ≤ i, j < n.
Could you do this in O(n) runtime?
Example:
Input: [3, 10, 5, 25, 2, 8]
Output: 28
Explanation: The maximum result is 5 ^ 25 = 28.
解题方法
依次遍历每一位
这个题不是很会,不过学到了异或操作的一个重要性质:a^b = c, 则有 a^c = b,且 b^c = a;
因此如果相求最大的c,可以把c设成1,看b存在不存在给定的数组当中。
下面的内容来自:https://kingsfish.github.io/2017/12/15/Leetcode-421-Maximum-XOR-of-Two-Numbers-in-an-Array/ 这个文章很好,讲的很详细大体能明白。
我们还需要用上一个异或的特性,假设a和b产生了最终的答案max,即a ^ b = x,那么根据异或的特性,a ^ x = b。同理,a和b的最高位(前n位)也有相同的性质。
先以最高位为例子,我们可以把所有的数字的最高位放到一个HashSet里面,然后使用1与set里面的所有数字进行异或,如果得出的结果仍然在set里面,那么最终结果的最高位必然为1,否则为0。也即,先假定结果为1,然后与set中所有数字异或,假定a与1异或得到结果b(a ^ 1 = b),而b仍然在set里面,那么说明set中有两个数字异或能得到1(a ^ b = 1)。否则,set中没有两个数字能够异或得到1,那么最终结果的最高位为1的假设失败,说明最终结果的最高位为0。以此类推可以得到第二位、第三位。。。的数字。
再做一下推广,我们将所有数字的前N位放到一个HashSet里面,然后使用之前N-1位得到的最大值前缀prefix与set里面的所有数字进行异或,如果得出的结果仍然在set中,那么第N位必然为1,否则为0。
举个例子,给定数组[14, 11, 7, 2],二进制表示分别为[1110, 1011, 0111, 0010]。题目说了,数字最长不会超过32位,所以应从i = 31开始,但是所有数字中最多位4位数,简单起见,我直接从最高位i=3开始
1. i = 3, set = {1000, 0000} => max = 1000
2. i = 2, set = {1100, 1000, 0100, 0000} => max = 1100
3. i = 1, set = {1110, 1010, 0110, 0010} => max = 1100
4. i = 0, set = {1110, 1011, 0111, 0010} => max = 1100
Python代码:
class Solution(object):
def findMaximumXOR(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
ans = mask = 0
for x in range(32)[::-1]:
mask += 1 << x
prefixSet = set([n & mask for n in nums])
temp = ans | 1 << x
for prefix in prefixSet:
if temp ^ prefix in prefixSet:
ans = temp
break
return ans
C++代码:
class Solution {
public:
int findMaximumXOR(vector<int>& nums) {
int res = 0;
int mask = 0;
unordered_set<int> s;
for (int i = 31; i >= 0; i--) {
s.clear();
mask |= 1 << i;
for (int num : nums) {
s.insert(num & mask);
}
int tmp = res | (1 << i);
for (int pre : s) {
if (s.count(tmp ^ pre)) {
res = tmp;
break;
}
}
}
return res;
}
};
前缀树
使用Trie也能做,但是我还没有想明白。。
日期
2018 年 3 月 7 日
2018 年 12 月 19 日 —— 感冒了,好难受
【LeetCode】421. Maximum XOR of Two Numbers in an Array 解题报告(Python & C++)的更多相关文章
- [LeetCode] 421. Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字
Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...
- [LeetCode] 421. Maximum XOR of Two Numbers in an Array(位操作)
传送门 Description Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Fin ...
- leetcode 421.Maximum XOR of Two Numbers in an Array
题目中给定若干个数,然后任意选定两个数使得其异或值最大. 先利用样例中的: 3 10 5 25 2 8 这些数转换为二进制来看的话那么是先找到最高位的1然后与数组中其他的数相与后的数值保存到set中去 ...
- 【leetcode】421. Maximum XOR of Two Numbers in an Array
题目如下: 解题思路:本题的难点在于O(n)的复杂度.为了减少比较的次数,我们可以采用字典树保存输入数组中所有元素的二进制的字符串.接下来就是找出每个元素的异或的最大值,把需要找最大值的元素转成二进制 ...
- 421. Maximum XOR of Two Numbers in an Array——本质:利用trie数据结构查找
Given a non-empty array of numbers, a0, a1, a2, - , an-1, where 0 ≤ ai < 231. Find the maximum re ...
- 421 Maximum XOR of Two Numbers in an Array 数组中两个数的最大异或值
给定一个非空数组,数组中元素为 a0, a1, a2, … , an-1,其中 0 ≤ ai < 231 .找到 ai 和aj 最大的异或 (XOR) 运算结果,其中0 ≤ i, j < ...
- 421. Maximum XOR of Two Numbers in an Array
这题要求On时间复杂度完成, 第一次做事没什么思路的, 答案网上有不贴了, 总结下这类题的思路. 不局限于这个题, 凡是对于这种给一个 数组, 求出 xxx 最大值的办法, 可能上来默认就是dp, ...
- LeetCode 421. 数组中两个数的最大异或值(Maximum XOR of Two Numbers in an Array) 71
421. 数组中两个数的最大异或值 421. Maximum XOR of Two Numbers in an Array 题目描述 给定一个非空数组,数组中元素为 a0, a1, a2, - , a ...
- [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字
Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...
随机推荐
- js变量作为数组对象的键值方法
js变量作为数组对象的键值方法,变量键值获取数组值 js也可以像php的数组一样用下标获取数组的值,方法是: var arr = {'key':'abc'}; var key = 'key'; con ...
- day07 Linux配置修改
day07 Linux配置修改 昨日回顾 1.系统目录 /etc :系统配置目录 /bin-> /usr/bin :保存常用命令的目录 /root :超级管理员目录 /home :普通管理员目录 ...
- Fragment放置后台很久(Home键退出很长时间),返回时出现Fragment重叠解决方案
后来在google查到相关资料,原因是:当Fragment长久不使用,系统进行回收,FragmentActivity调用onSaveInstanceState保存Fragment对象.很长时间后,再次 ...
- Linux基础命令---vmstat显示虚拟内存状态
vmstat vmstat指令用来显示虚拟内存使用状态,同时也可以显示进程.cpu活动情况.vmstat报告有关进程.内存.分页.块IO.陷阱和CPU活动的信息.生成的第一份报告给出了自上次重新启动以 ...
- vue2 安装打包部署
vue2项目搭建记录 mkdir -p /opt/wks/online_pre/1006cd /opt/wks/online_pre/1006mkdir hongyun-ui /opt/code/vu ...
- NSURLSessionDownloadTask实现大文件下载
- 4.1 涉及知识点(1)使用NSURLSession和NSURLSessionDownload可以很方便的实现文件下载操作 第一个参数:要下载文件的url路径 第二个参数:当接收完服务器返回的数据 ...
- win10安装两台mysql-5.7.31实例
1. 下载 mysql5.7.31 压缩包: (1)百度云下载: 链接:https://pan.baidu.com/s/1jgxfvIYzg8B8ahxU9pF6lg 提取码:fiid (2)官网下载 ...
- request.getRequestDispatcher()和response.sendRedirect()区别
一.request.getRequestDispatcher().forward(request,response): 1.属于转发,也是服务器跳转,相当于方法调用,在执行当前文件的过程中转向执行目标 ...
- layui-入门
1.下载layui 2.导入layui <title>开始使用layui</title> <!-- 导入js样式 --> <link rel="st ...
- 【力扣】剑指 Offer 25. 合并两个排序的链表
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的. 示例1: 输入:1->2->4, 1->3->4输出:1->1->2->3-> ...