Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >​2021-05-13:数组中所有数都异或起来的结果,叫做异或和。

​2021-05-13:数组中所有数都异或起来的结果,叫做异或和。

原创
作者头像
福大大架构师每日一题
修改于 2021-05-14 02:14:10
修改于 2021-05-14 02:14:10
4360
举报

2021-05-13:数组中所有数都异或起来的结果,叫做异或和。给定一个数组arr,返回arr的最大子数组异或和。

前缀树。一个数,用二进制表示,0走左边分支,1走右边分支。

时间复杂度:O(N)。

代码用golang编写。代码如下:

代码语言:txt
AI代码解释
复制
package main

import (
    "fmt"
    "math"
)

func main() {
    arr := []int{-1, 2}
    ret := maxXorSubarray2(arr)
    fmt.Println(ret)
}

// 前缀树的Node结构
// nexts[0] -> 0方向的路
// nexts[1] -> 1方向的路
// nexts[0] == null 0方向上没路!
// nexts[0] != null 0方向有路,可以跳下一个节点
// nexts[1] == null 1方向上没路!
// nexts[1] != null 1方向有路,可以跳下一个节点
type Node struct {
    nexts []*Node
}

func twoSelectOne(condition bool, a int, b int) int {
    if condition {
        return a
    } else {
        return b
    }

}

func NewNode() *Node {
    ret := &Node{}
    ret.nexts = make([]*Node, 2)
    return ret
}

// 基于本题,定制前缀树的实现
type NumTrie struct {
    // 头节点
    head *Node
}

func NewNumTrie() *NumTrie {
    ret := &NumTrie{}
    ret.head = NewNode()
    return ret
}

func (this *NumTrie) add(newNum int) {
    cur := this.head
    for move := 63; move >= 0; move-- {
        path := (newNum >> move) & 1
        if cur.nexts[path] == nil {
            cur.nexts[path] = NewNode()
        }
        cur = cur.nexts[path]
    }
}

// 该结构之前收集了一票数字,并且建好了前缀树
// num和 谁 ^ 最大的结果(把结果返回)
func (this *NumTrie) maxXor(num int) int {
    cur := this.head
    ans := 0
    for move := 63; move >= 0; move-- {
        // 取出num中第move位的状态,path只有两种值0就1,整数
        path := (num >> move) & 1
        // 期待遇到的东西
        best := twoSelectOne(move == 63, path, path ^ 1)
        // 实际遇到的东西
        best = twoSelectOne(cur.nexts[best] != nil, best, best ^ 1)
        // (path ^ best) 当前位位异或完的结果
        ans |= (path ^ best) << move
        cur = cur.nexts[best]
    }
    return ans
}

// O(N)
func maxXorSubarray2(arr []int) int {
    if len(arr) == 0 {
        return 0
    }
    max := math.MinInt64
    // 0~i整体异或和
    xor := 0
    numTrie := NewNumTrie()
    numTrie.add(0)
    for i := 0; i < len(arr); i++ {
        xor ^= arr[i] // 0 ~ i
        max = getMax(max, numTrie.maxXor(xor))
        numTrie.add(xor)
    }
    return max
}

func getMax(a int, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

执行结果如下:

图片
图片

左神java代码复制版

左神java代码原版

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
​2021-05-14:给定一个数组arr,想知道arr中哪两个数的异或结果最大。
2021-05-14:给定一个数组arr,想知道arr中哪两个数的异或结果最大。返回最大的异或结果。
福大大架构师每日一题
2021/05/14
5250
​2021-05-14:给定一个数组arr,想知道arr中哪两个数的异或结果最大。
2021-08-07:与数组中元素的最大异或值。给你一个由非负
2021-08-07:与数组中元素的最大异或值。给你一个由非负整数组成的数组 nums 。另有一个查询数组 queries ,其中 queriesi = xi, mi 。第 i 个查询的答案是 xi 和任何 nums 数组中不超过 mi 的元素按位异或(XOR)得到的最大值。换句话说,答案是 max(numsj XOR xi) ,其中所有 j 均满足 numsj <= mi 。如果 nums 中的所有元素都大于 mi,最终答案就是 -1 。返回一个整数数组 answer 作为查询的答案,其中 answer.length == queries.length 且 answeri 是第 i 个查询的答案。
福大大架构师每日一题
2021/08/07
2760
2021-08-07:与数组中元素的最大异或值。给你一个由非负
2021-05-17:数组中所有数都异或起来的结果,叫做异或和。给定一个数组arr,可以任意切分成若干个不相交的子数组。其中一定
2021-05-17:数组中所有数都异或起来的结果,叫做异或和。给定一个数组arr,可以任意切分成若干个不相交的子数组。其中一定存在一种最优方案,使得切出异或和为0的子数组最多。返回这个最多数量。
福大大架构师每日一题
2021/08/05
3300
2021-06-13:如果一个节点X,它左树结构和右树结构完全一
2021-06-13:如果一个节点X,它左树结构和右树结构完全一样,那么我们说以X为头的树是相等树。给定一棵二叉树的头节点head,返回head整棵树上有多少棵相等子树。
福大大架构师每日一题
2021/06/14
3360
2021-06-13:如果一个节点X,它左树结构和右树结构完全一
2021-09-05:单词搜索 II。给定一个 m x n 二维字符网格 bo
2021-09-05:单词搜索 II。给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words,找出所有同时在二维网格和字典中出现的单词。单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。力扣212。
福大大架构师每日一题
2021/09/05
2730
给定一个数组,求子数组的最大异或和
一、给定一个数组,求子数组的最大异或和 解法一:O(N^3) public static int getMaxEOR1(int[] arr){ int max = Integer.MIN_VALUE; for (int i = 0 ; i < arr.length ;i++){ for (int start = 0 ;start <= i;start++) { int res = 0; for (int j = start; j
大学里的混子
2019/02/25
1.1K0
2021-05-22:假设所有字符都是小写字母, 大字符串是str,
2021-05-22:假设所有字符都是小写字母, 大字符串是str,arr是去重的单词表, 每个单词都不是空字符串且可以使用任意次。使用arr中的单词有多少种拼接str的方式。 返回方法数。
福大大架构师每日一题
2021/05/22
2080
2021-05-22:假设所有字符都是小写字母, 大字符串是str,
2022-02-20:设计内存文件系统。 设计一个内存文件系统,模
ls: 以字符串的格式输入一个路径。如果它是一个文件的路径,那么函数返回一个列表,仅包含这个文件的名字。如果它是一个文件夹的的路径,那么返回该 文件夹内 的所有文件和子文件夹的名字。你的返回结果(包括文件和子文件夹)应该按字典序排列。
福大大架构师每日一题
2022/02/20
3710
2021-10-16:单词拆分 II。给定一个非空字符串 s 和一个包
2021-10-16:单词拆分 II。给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。说明:分隔时可以重复使用字典中的单词。你可以假设字典中没有重复的单词。力扣140。
福大大架构师每日一题
2021/10/16
3020
给定一个数组,求子数组的最大异或和
 直接说这道题时间复杂度O(n)的做法,构建前缀树。假设将0-0、0-1、0-2、...、0-i-1的异或结果全部装在前缀树中,那么以i结尾的最大异或和就是0到某一位置x的异或结果和i异或结果最大,举个例子,假设x是3,0-3的异或结果和i进行异或得到的结果最大,那么就说明4-i的异或结果是最大的。  但是如何知道x到底是多少,换句话说,0-x中哪个值和i进行异或得到的结果最大。其实这个也比较好想,假设i是0100(最高位0是符号位),只需要沿着前缀树找到0011,异或出来的结果就是0111,一定就是最大的,如果不能刚好找到合适的,那就有什么选什么,只要保证从最高位开始往下每次的决策是最优的就行  有一种特殊情况,假设i还是0100,但是此时前缀树中最高位只有1,没有0,那么最高位得出的异或结果永远是负数,后面的位应该如何选?其实也是按照最优决策去选,假设异或结果是1111,那么转换为十进制就是-1,绝对没有比这还大的负数了
mathor
2018/09/19
1.7K0
2021-05-22:假设所有字符都是小写字母, 大字符串是str,arr是去重的单词表, 每个单词都不是空字符串且可以使用任意
2021-05-22:假设所有字符都是小写字母, 大字符串是str,arr是去重的单词表, 每个单词都不是空字符串且可以使用任意次。使用arr中的单词有多少种拼接str的方式。返回方法数。
福大大架构师每日一题
2021/08/05
3750
2021-10-15:单词拆分。给定一个非空字符串 s 和一个包含
2021-10-15:单词拆分。给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。说明:拆分时可以重复使用字典中的单词。你可以假设字典中没有重复的单词。力扣139。
福大大架构师每日一题
2021/10/15
4330
2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。实现 WordFilter 类:WordF
2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。
福大大架构师每日一题
2023/06/08
3660
2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。实现 WordFilter 类:WordF
2021-05-17:数组中所有数都异或起来的结果,叫做异或和
2021-05-17:数组中所有数都异或起来的结果,叫做异或和。给定一个数组arr,可以任意切分成若干个不相交的子数组。其中一定存在一种最优方案,使得切出异或和为0的子数组最多。返回这个最多数量。
福大大架构师每日一题
2021/05/17
4940
2021-05-17:数组中所有数都异或起来的结果,叫做异或和
2022-01-29:连接词。 给你一个 不含重复 单词的字符串数组
给你一个 不含重复 单词的字符串数组 words ,请你找出并返回 words 中的所有 连接词 。
福大大架构师每日一题
2022/01/29
3090
2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。 实现 WordFilter 类: WordFilter(string[]
2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。
福大大架构师每日一题
2023/04/17
3770
2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。 实现 WordFilter 类: WordFilter(string[]
2021-08-02:按公因数计算最大组件大小。给定一个由不同
2021-08-02:按公因数计算最大组件大小。给定一个由不同正整数的组成的非空数组 A,考虑下面的图:有 A.length 个节点,按从 A0 到 AA.length - 1 标记;只有当 Ai 和 Aj 共用一个大于 1 的公因数时,Ai 和 Aj 之间才有一条边。返回图中最大连通组件的大小。
福大大架构师每日一题
2021/08/02
4560
2021-08-02:按公因数计算最大组件大小。给定一个由不同
2021-04-30:一条直线上有居民点,邮局只能建在居民点上。给定一个有序正数数组arr
2021-04-30:一条直线上有居民点,邮局只能建在居民点上。给定一个有序正数数组arr,每个值表示 居民点的一维坐标,再给定一个正数 num,表示邮局数量。选择num个居民点建立num个 邮局,使所有的居民点到最近邮局的总距离最短,返回最短的总距离。【举例】arr=1,2,3,4,5,1000,num=2。第一个邮局建立在 3 位置,第二个邮局建立在 1000 位置。那么 1 位置到邮局的距离 为 2, 2 位置到邮局距离为 1,3 位置到邮局的距离为 0,4 位置到邮局的距离为 1, 5 位置到邮局的距 离为 2,1000 位置到邮局的距离为 0。这种方案下的总距离为 6, 其他任何方案的总距离都不会 比该方案的总距离更短,所以返回6。
福大大架构师每日一题
2021/05/04
4880
2021-04-30:一条直线上有居民点,邮局只能建在居民点上。给定一个有序正数数组arr
2021-08-27:正常的里程表会依次显示自然数表示里程,吉
2021-08-27:正常的里程表会依次显示自然数表示里程,吉祥的里程表会忽略含有4的数字而跳到下一个完全不含有4的数。正常:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 X。吉祥:1 2 3 5 6 7 8 9 10 11 12 13 15 16 17 ... 38 39 50 51 52 53 55。给定一个吉祥里程表的数字num(当然这个数字中不含有4)。返回这个数字代表的真实里程。
福大大架构师每日一题
2021/08/27
2820
2021-08-27:正常的里程表会依次显示自然数表示里程,吉
2021-11-22:给定一个正数数组arr,表示每个小朋友的得
任何两个相邻的小朋友,如果得分一样,怎么分糖果无所谓,但如果得分不一样,分数大的一定要比分数少的多拿一些糖果;
福大大架构师每日一题
2021/11/22
2010
推荐阅读
​2021-05-14:给定一个数组arr,想知道arr中哪两个数的异或结果最大。
5250
2021-08-07:与数组中元素的最大异或值。给你一个由非负
2760
2021-05-17:数组中所有数都异或起来的结果,叫做异或和。给定一个数组arr,可以任意切分成若干个不相交的子数组。其中一定
3300
2021-06-13:如果一个节点X,它左树结构和右树结构完全一
3360
2021-09-05:单词搜索 II。给定一个 m x n 二维字符网格 bo
2730
给定一个数组,求子数组的最大异或和
1.1K0
2021-05-22:假设所有字符都是小写字母, 大字符串是str,
2080
2022-02-20:设计内存文件系统。 设计一个内存文件系统,模
3710
2021-10-16:单词拆分 II。给定一个非空字符串 s 和一个包
3020
给定一个数组,求子数组的最大异或和
1.7K0
2021-05-22:假设所有字符都是小写字母, 大字符串是str,arr是去重的单词表, 每个单词都不是空字符串且可以使用任意
3750
2021-10-15:单词拆分。给定一个非空字符串 s 和一个包含
4330
2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。实现 WordFilter 类:WordF
3660
2021-05-17:数组中所有数都异或起来的结果,叫做异或和
4940
2022-01-29:连接词。 给你一个 不含重复 单词的字符串数组
3090
2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。 实现 WordFilter 类: WordFilter(string[]
3770
2021-08-02:按公因数计算最大组件大小。给定一个由不同
4560
2021-04-30:一条直线上有居民点,邮局只能建在居民点上。给定一个有序正数数组arr
4880
2021-08-27:正常的里程表会依次显示自然数表示里程,吉
2820
2021-11-22:给定一个正数数组arr,表示每个小朋友的得
2010
相关推荐
​2021-05-14:给定一个数组arr,想知道arr中哪两个数的异或结果最大。
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档