每日一题411数组中两个数的最大异或值(哈希表、前缀树:实现前缀树)

数组中两个数的最大异或值(哈希表、前缀树:实现前缀树)

LeetCode题目:https://leetcode.cn/problems/maximum-xor-of-two-numbers-in-an-array/

哈希表解法

  本题使用哈希表方法主要运用到一个定理:异或满足算法交换律。即如果a^b = c,那么必然 b ^ c = a。且数组中的元素都在 [ 0 , 2 31 ) [0,2^{31}) [0,231),因此可以确定数值的最高位是30位。

  因此,可以假设从最高位开始进行计算。依次确定每一位是0还是1,即将上一次的计算值x乘以2再加上1,就是当前理想的最大值(因为此时新增为假设为1)

  因此便可以应用异或的交换律,将数组中的数值num右移k位以映射为当前从30位到第k位的二进制数值。

  再分别与当前的理想最大值进行异或。如果异或后的计算结果可以在哈希表中查询到,则说明存在num_i和num_j,可以异或组成最大值。

  可能有人会疑问,这样循环30次,会不会可能导致每次异或的i和j,与上一轮k的不一样,那不就不符合唯一的i 和 j了嘛?

  其实因为算法从高位计算,如果高位已经确定可以到达1,那么后面就由这个结果倒推罢了(交换律,在高位已经置1的条件下进行接下来的推导)因此并不会出现这种问题。
  代码如下:

class Solution {static final int HIGH_BIT = 30;public int findMaximumXOR(int[] nums) {int x = 0;for (int k = HIGH_BIT; k >= 0; k--) {Set<Integer> seen = new HashSet<Integer>();//通过哈希表构建第30位到第k位的num数据for (int num :nums) {seen.add(num >> k);}//当前理想情况下x的最大值(即新增的第k位可以异或取1)int x_Next = x * 2 + 1;boolean found = false;for (int num: nums) {if (seen.contains(x_Next ^ (num >> k))) //异或满足交换律,所以num i和 num j异或是否可以得到当前位标记为1的数x_Next{found = true;break;}}if (found) {x = x_Next;}else {x = x_Next - 1;//如果没有找到,则说明k位不能被置为1,所以-1即可}}return x;}
}

前缀树解法

  首先先要了解前缀树是什么?Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。

相关题目:实现 Trie (前缀树)

LeetCode题目:https://leetcode.cn/problems/implement-trie-prefix-tree/

  对于字符串来说,相当于一个26叉树,每个分叉对应一个字母,从开始到结尾依次对应字符每个位置是否存在该字符。

代码如下:

class Trie {private Trie[] children;private boolean isEnd;public Trie() {children = new Trie[26];isEnd = false;}public void insert(String word) {Trie node = this;for (int i = 0; i < word.length(); i++) {char ch = word.charAt(i);int index = ch - 'a';if (node.children[index] == null) {node.children[index] = new Trie();}node = node.children[index];}node.isEnd = true;}public boolean search(String word) {Trie node = searchPrefix(word);return node != null && node.isEnd;}public boolean startsWith(String prefix) {return searchPrefix(prefix) != null;}private Trie searchPrefix(String prefix) {Trie node = this;for (int i = 0; i < prefix.length(); i++) {char ch = prefix.charAt(i);int index = ch - 'a';if (node.children[index] == null) {return null;}node = node.children[index];}return node;}
}/*** Your Trie object will be instantiated and called as such:* Trie obj = new Trie();* obj.insert(word);* boolean param_2 = obj.search(word);* boolean param_3 = obj.startsWith(prefix);*/

字典树的应用

个人理解,字典树适合查询一些可重复的状态类别,比如当前需要查询的数据,是之前所有已经放入的数据总和的情况下,字典树十分方便。

  可以将字典树应用在该题目上,主要用到的核心点有: 0 ≤ i ≤ j < n 0 ≤ i ≤ j < n 0ij<n ,以及逐位进行异或的思想。

  首先假定字典树是从高位开始统计每一位的0或者1,且因为异或为i与j索引数字的异或。所以j只要保证一直比i要大1即可。

  此时维护一个公共的字典树,并将其与num_j进行按位异或运算。并随着i的更新不断更新字典树内部的索引。即可完成。

代码如下:

class Solution {Trie root = new Trie();static final int HIGH_BIT = 30;public int findMaximumXOR(int[] nums) {int x = 0;for (int i = 1; i < nums.length; i++) {add(nums[i - 1]);x = Math.max(x, check(nums[i]));}return x;}private void add(int num) {Trie cur = root;for (int k = HIGH_BIT; k >= 0 ; k--) {int bit = (num >> k) & 1;if (cur.children[bit] == null) {cur.children[bit] = new Trie(); } cur = cur.children[bit];}}private int check(int num) {Trie cur = root;int x = 0;for (int k = HIGH_BIT; k >= 0; k--) {int bit = (num >> k) & 1;if (bit == 0) {if (cur.children[1] != null) {cur = cur.children[1];x = x * 2 + 1;}else if (cur.children[0] != null){x = x * 2;cur = cur.children[0];}else {break;}}else {if (cur.children[0] != null) {cur = cur.children[0];x = x * 2 + 1;}else if (cur.children[1] != null){x = x * 2;cur = cur.children[1];}else {break;}}}return x;}
}class Trie{public Trie[] children;public Trie() {children = new Trie[2];}
}

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

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

相关文章

【Spring MVC】Spring MVC框架的介绍及其使用方法

目录 一、MVC模式 1.1 MVC模式的发展 1.1.1 Model1 模型 1.1.2 Model2 模型 1.2 MVC模式简介 1.模型(Model) 2.视图(View) 3.控制器(Controller) 二、Spring MVC模型简介 三、Spring MVC 六大核心组件 3.1 六大组件简介 1.前端控制器 DispatcherServlet&#xff08…

Notepad++下载、使用

下载 https://notepad-plus-plus.org/downloads/ 安装 双击安装 选择安装路径 使用 在文件夹中搜索 文件类型可以根据需要设置 如 *.* 说明是所有文件类型&#xff1b; *.tar 说明是所有文件后缀是是tar的文件‘&#xff1b;

多个PDF发票合并实现一张A4纸打印2张电子/数电发票功能

python教程79--A4纸增值税电子发票合并打印_python 打印 发票设置_颐街的博客-CSDN博客文章浏览阅读7.9k次。接上篇https://blog.csdn.net/itmsn/article/details/121902974?spm1001.2014.3001.5501一张A4纸上下2张增值税电子发票实现办法。使用环境&#xff1a;python3.8、ma…

JAVA 实现PDF转图片(pdfbox版)

依赖&#xff1a; pdf存放路径 正文开始&#xff1a; pdf转换多张图片、长图 Test void pdf2Image() {String dstImgFolder "";String PdfFilePath "";String relativelyPathSystem.getProperty("user.dir");PdfFilePath relativelyPath &qu…

企业之间的竞争,ISO三体系认证至关重要!

ISO三体系认证是指ISO 9001质量管理体系认证、ISO 14001环境管理体系认证、ISO 45001(OHSAS18001)职业健康安全管理体系认证。企业&#xff08;组织&#xff09;自愿申请、通过ISO三体系认证&#xff0c;并贯彻落实&#xff0c;确实能获益多多。 ISO 9001质量管理体系 我们经…

Scala的类和对象

1. 初识类和对象 Scala 的类与 Java 的类具有非常多的相似性&#xff0c;示例如下&#xff1a; // 1. 在 scala 中&#xff0c;类不需要用 public 声明,所有的类都具有公共的可见性 class Person {// 2. 声明私有变量,用 var 修饰的变量默认拥有 getter/setter 属性private var…

Ps:PSDT 模板文件

自 Photoshop CC 2015.5 版以后&#xff0c;Ps 中新增了一种文件格式&#xff1a;.PSDT。 说明&#xff1a; PSD、PDD、PSDT 都是 Ps 的专用文件格式&#xff0c;需要继续在 Ps 中进行编辑的文件可存为此类格式。 PSD Photoshop document Photoshop 默认文档格式&#xff0c;支…

选择适合你的办公桌:提高工作效率的关键

​在如今的数字时代&#xff0c;越来越多的人将办公桌移到家里或办公室。但是&#xff0c;如何选择适合你的办公桌可能是个挑战。不同的工作需要和工作空间大小会影响你的选择。下面是一些简单的建议&#xff0c;帮助你找到适合你的办公桌&#xff0c;提高工作效率。 首先&…

使用pytorch处理自己的数据集

目录 1 返回本地文件中的数据集 2 根据当前已有的数据集创建每一个样本数据对应的标签 3 tensorboard的使用 4 transforms处理数据 tranfroms.Totensor的使用 transforms.Normalize的使用 transforms.Resize的使用 transforms.Compose使用 5 dataset_transforms使用 1 返回本地…

Android 基于 J2V8 运行 JavasScript 实践

V8 引擎是由 Google 开源的 JavaScript 引擎&#xff0c;Chrome 就是基于 V8 开发&#xff0c;V8 是跨平台的&#xff0c;J2V8 基于 V8 进行开发&#xff0c;使得 js 代码能够在 Android 平台上脱离 WebView 运行。目前&#xff0c;也有很多关于 Android J2V8 的文章&#xff0…

java int char string互相转换和判断

java int 转 ascii码 数字-> ascii码 System.out.println(7 0);ascii码-> 数字 System.out.println(9 - 0);char ch 5; ch (char)(ch -0); //实际计算时是默认将char类型的ch转换为int类型98; 然后将 97 强转为 a System.out.println(ch); // 5 System.out.println…

@RunWith(SpringRunner.class)注解的作用

通俗点&#xff1a; RunWith(SpringRunner.class)的作用表明Test测试类要使用注入的类&#xff0c;比如Autowired注入的类&#xff0c;有了RunWith(SpringRunner.class)这些类才能实例化到spring容器中&#xff0c;自动注入才能生效 官方点&#xff1a; RunWith 注解是JUnit测…

【数据结构】深入浅出理解快速排序背后的原理 以及 版本优化【万字详解】(C语言实现)

快速排序 快速排序递归实现前言一、Hoare版本&#xff08;一&#xff09;算法运行图例&#xff08;二&#xff09;算法核心思路&#xff08;三&#xff09;算法实现步骤&#xff08;1&#xff09;单趟&#xff08;2&#xff09;多趟 &#xff08;四&#xff09;码源详解 递归实…

npm install报 ERESOLVE unable to resolve dependency tree

三四年前的一个项目&#xff0c;打开&#xff0c;npm install 一下&#xff0c;结果报 ERESOLVE unable to resolve dependency tree。 以前install都一切顺利&#xff0c;现在就不行&#xff0c;那很大的可能是npm的版本不同。 PS D:\workSpace\code\*-admin-ui-master> n…

LeetCode热题100——滑动窗口

滑动窗口 1. 无重复字符的最长序列2. 找对字符中所有字母的异位词 1. 无重复字符的最长序列 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 // 题解&#xff1a;利用set集合查询滑窗内是否存在重复字符 int lengthOfLongestSubstring(string…

单元测试反射注解

单元测试 就是针对最小的功能单元(方法)&#xff0c;编写测试代码对其进行正确性测试。 咱们之前是如何进行单元测试的&#xff1f;有啥问题 &#xff1f; Junit单元测试框架 可以用来对方法进行测试&#xff0c;它是由Junit公司开源出来的 具体步骤 Junit框架的常见注解…

『亚马逊云科技产品测评』活动征文|占了个便宜,12个月的免费云服务器

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 在群里看到有小伙伴说亚马逊可以免费试用服务器&#xff0c;这种好事不得…

Jenkins自动化部署简单配置

下载安装jenkins 安装Jenkins步骤 点击Next的时候会有jdk版本跟Jenkins版本不符合的情况 1. 看下任务管理器内Jenkins服务是否启动&#xff0c;在浏览器里面输入localhost:2023&#xff08;端口号是安装时输入的&#xff09; 2. 根据路径找到放置密码的文件&#xff08;C…

JS冒泡排序(介绍如何执行)

想必大家都多多少少了解过一点排序&#xff0c;让我为大家介绍一下冒泡排序吧&#xff01; 假设我们现在有一个数组[2&#xff0c;4&#xff0c;3&#xff0c;5&#xff0c;1] 我们来分析一下&#xff1a; 1.一共需要的趟数 我们用外层for循环 5个数据我们一共需要走4躺 长度就…

用golang实现一个基于interface的多态示例,展示其使用场景和优劣性。

以下是一个简单的基于interface的多态示例&#xff0c;该示例展示了如何通过使用interface来实现多个不同类型的结构体的共同行为。具体示例如下&#xff1a; package mainimport "fmt"type Animal interface {Speak() string }type Dog struct {Name string }func …