• leetcode_421数组中两个数的最大异或值


    1. 题意

    求数组中两个数的最大异或

    数组中两个数的最大异或值

    2. 题解

    2.1 哈希表

    a i ⊕ a j = x a_i \oplus a_j = x aiaj=x
    所以
    a i = x ⊕ a j a_i =x \oplus a_j ai=xaj

    考虑 a i 、 a j a_i、a_j aiaj的每一位的所有情况

    b i t ( a i , k ) bit(a_i,k) bit(ai,k) b i t ( a j , k ) bit(a_j,k) bit(aj,k) b i t ( x , k ) bit(x,k) bit(x,k)
    000
    011
    101
    110

    我们可以从最高位开始尝试,是否能使第 k k k位为1。

    即对 p r e ( k , a j ) pre(k,a_j) pre(k,aj) p r e S e t ( k ) preSet(k) preSet(k)中是否有 x ⊕ p r e ( k , a j ) x \oplus pre(k,a_j) xpre(k,aj)使得枚举的最大前缀 x x x成立。

    • 代码
    class Solution {
    public:
    
       
    
        int findMaximumXOR(vector<int>& nums) {
    
            int ans = 0;
            for ( int i = 30; i > -1; --i ) {
    
                unordered_set<int> preSet;
    
                for ( int num: nums) {
                    preSet.insert( num >> i);
                }
    
                ans = ans << 1 | 1;
                bool find = false;
                for (int num: nums) {
                    if ( preSet.count( (num >> i) ^ ans )) {
                        find = true;
                        break;
                    }
                }
                if ( !find)
                    ans--;
    
            }     
            
    
    
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    2.2 前缀树

    可以将所有值插入到一颗0-1前缀树中,然后再遍历每个值,对于每一位尽量选择它的翻转值,如果
    树中有该路径的话。最后再取最大值。

    class Solution {
    public:
    
        class Trie {
        public:
            Trie():isEnd(false),left(nullptr),right(nullptr)
            {}
    
            void insert(int v) {
                Trie *cur = this;
    
    
                for ( int bit = 30; bit > -1; --bit) {
                    int c = (1 << bit) & v;
    
                    if (!c) {
                        
                        if (cur->left == nullptr) {
                            cur->left = new Trie();
                        }
                        cur = cur->left;
                    }
                    else {
                        if ( cur->right == nullptr)
                            cur->right = new Trie();
                        cur = cur->right;
                    }
                }
                cur->isEnd = true;
            }
            int getMaxXor(int v) {
    
                int ans = 0;
                Trie *cur = this;
                for ( int bit = 30; bit > -1; --bit) {
                    int c = (1 << bit) & v;
    
                    if (c) {
                        if ( cur->left) {
                            cur = cur->left;
                            ans |= (1 << bit);
                        }
                        else {
                            cur = cur->right;
                        }
                    }
                    else {
                        if ( cur->right ) {
                            cur  = cur->right;
                            ans |= (1 << bit);
                        }
                        else {
                            cur = cur->left;
                        }
                    }
                }
    
                return ans; 
            }
    
        private:
            Trie *left;
            Trie *right;
            bool isEnd;
        };
    
        int findMaximumXOR(vector<int>& nums) {
            
            Trie trie;
            for (int num: nums)
                trie.insert(num);
    
            int ans = 0;
    
            for (int num:nums) {
                ans = max(ans, trie.getMaxXor(num) );
            }
    
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
  • 相关阅读:
    军用软件开发文档通用要求常见缩略语
    关于设置Windows文件夹区分大小写
    二叉树oj题集(LeetCode)
    机器学习笔记之指数族分布——最大熵角度观察指数族分布(二)最大熵定理与指数族分布的关系
    一篇适合大一同学的算法学习建议
    设计模式的二十三招式——以入门者角度说说设计模式
    Linux系统日志采集
    一篇带你看懂异步:promise、async await
    transition和animation的区别?
    PMP项目管理中的各种图
  • 原文地址:https://blog.csdn.net/bdn_nbd/article/details/134234215