🌕🌕🌗 421. 数组䞭䞀䞪数的最倧匂或倌

吞䜛童子2022幎10月10日
  • algorithm
  • å­—å…žæ ‘
  • 扟规埋
倧纊 2 分钟

🌕🌕🌗 421. 数组䞭䞀䞪数的最倧匂或倌

隟床: 🌕🌕🌗

问题描述

img_3.png


解法

class Solution {
    public int findMaximumXOR(int[] nums) {
        // 思路
        // 构造字兞树只有巊右䞀䞪节点分别衚瀺 0 & 1
        // 1. 遍历元玠初始化字兞树
        // 2. 定䜍到銖节点该节点倄 cur.left != null && cur.right != null 正奜出现 0 & 1 
        // 3. 递園扟到最倧运算结果
        Node root = new Node(0);
        // 1. 倍杂床 O(30 * N)
        for(int i: nums) {
            // 2^31 - 1 最高䜍的 1 所圚䜍眮䞺 1 <<< 30
            int monitor = (1 << 30); // 初始参照倌䞎之匂或刀断该䜍是吊䞺 1
            Node tmp = root;
            while(monitor > 0) {
                // 根据每䜍的倌进行巊右节点的插入
                int cur = (monitor & i);
                if(cur == 0) {
                    if(tmp.left == null) {
                        tmp.left = new Node(0);
                    }
                    tmp = tmp.left;
                } else {
                    if(tmp.right == null) {
                        tmp.right = new Node(1);
                    }
                    tmp = tmp.right;
                }
                monitor >>>= 1;
            }
        }
        // 2. 倍杂床 O(31)
        Node node = root;
        int pow = 30;
        // node != null 䞺了防止只有䞀条分叉线富臎 node == null
        while(node != null && (node.left == null || node.right == null)) {
            if(node.left == null) {
                node = node.right;
            } else {
                node = node.left;
            }
            pow --;
        }
        if(node == null) {
            return 0;
        }
        // node.left != null && node.right != null
        // 出现同时存圚 0 & 1 的节点
        return mySol(node.left, node.right, pow);
    }

    private int mySol(Node a, Node b, int pow) {
        // 递園终止条件
        if(a == null || b == null) {
            return 0;
        }
        int res = 0;
        // 求 节点 a & 节点 b 的匂或倌 
        if(a.val != b.val) {
            // 该䜍莡献了䞀仜匂或倌
            res += (1 << pow);
        }
        // 刀断埀哪䞪方向递園
        // 每䞪节点有 2 种分支选择䜆若是节点只有䞀䞪子节点那么只剩䞋䞀条路
        if(a.left == null) {
            // a.right != null --> a 只胜走 right 方向最理想的情况是 b 胜走 left 方向
            // 刀断 b 走哪䞪方向
            if(b.left != null) {
                return res + mySol(a.right, b.left, pow - 1);
            } else {
                return res + mySol(a.right, b.right, pow - 1);
            }
        } else if(a.right == null) {
            // a.left != null
            if(b.right != null) {
                return res + mySol(a.left, b.right, pow - 1);
            } else {
                return res + mySol(a.left, b.left, pow - 1);
            }
        } else {
            // a.left != null && a.right != null
            // 䞍论走 b 的巊蟹还是右蟹总胜有䞀种选择满足同时出现 1 & 0 的情况
            return res + Math.max(mySol(a.left, b.right, pow - 1), mySol(a.right, b.left, pow - 1));
        }
    }
}

class Node {
    int val;
    Node left;
    Node right;
    public Node(int val) {
        this.val = val;
    }
}


蟓出

img_2.png

䞊次猖蟑于: 2022/10/10 䞋午8:43:48
莡献者: liuxianzhishou