返回介绍

solution / 1700-1799 / 1707.Maximum XOR With an Element From Array / README_EN

发布于 2024-06-17 01:03:15 字数 9740 浏览 0 评论 0 收藏 0

1707. Maximum XOR With an Element From Array

中文文档

Description

You are given an array nums consisting of non-negative integers. You are also given a queries array, where queries[i] = [xi, mi].

The answer to the ith query is the maximum bitwise XOR value of xi and any element of nums that does not exceed mi. In other words, the answer is max(nums[j] XOR xi) for all j such that nums[j] <= mi. If all elements in nums are larger than mi, then the answer is -1.

Return _an integer array _answer_ where _answer.length == queries.length_ and _answer[i]_ is the answer to the _ith_ query._

 

Example 1:

Input: nums = [0,1,2,3,4], queries = [[3,1],[1,3],[5,6]]
Output: [3,3,7]
Explanation:
1) 0 and 1 are the only two integers not greater than 1. 0 XOR 3 = 3 and 1 XOR 3 = 2. The larger of the two is 3.
2) 1 XOR 2 = 3.
3) 5 XOR 2 = 7.

Example 2:

Input: nums = [5,2,4,6,6,3], queries = [[12,4],[8,1],[6,3]]
Output: [15,-1,5]

 

Constraints:

  • 1 <= nums.length, queries.length <= 105
  • queries[i].length == 2
  • 0 <= nums[j], xi, mi <= 109

Solutions

Solution 1: Offline Query + Binary Trie

From the problem description, we know that each query is independent and the result of the query is irrelevant to the order of elements in $nums$. Therefore, we consider sorting all queries in ascending order of $m_i$, and also sorting $nums$ in ascending order.

Next, we use a binary trie to maintain the elements in $nums$. We use a pointer $j$ to record the current elements in the trie, initially $j=0$. For each query $[x_i, m_i]$, we continuously insert elements from $nums$ into the trie until $nums[j] > m_i$. At this point, we can query all elements not exceeding $m_i$ in the trie, and we take the XOR value of the element with the maximum XOR value with $x_i$ as the answer.

The time complexity is $O(m \times \log m + n \times (\log n + \log M))$, and the space complexity is $O(n \times \log M)$. Where $m$ and $n$ are the lengths of the arrays $nums$ and $queries$ respectively, and $M$ is the maximum value in the array $nums$. In this problem, $M \le 10^9$.

class Trie:
  __slots__ = ["children"]

  def __init__(self):
    self.children = [None] * 2

  def insert(self, x: int):
    node = self
    for i in range(30, -1, -1):
      v = x >> i & 1
      if node.children[v] is None:
        node.children[v] = Trie()
      node = node.children[v]

  def search(self, x: int) -> int:
    node = self
    ans = 0
    for i in range(30, -1, -1):
      v = x >> i & 1
      if node.children[v ^ 1]:
        ans |= 1 << i
        node = node.children[v ^ 1]
      elif node.children[v]:
        node = node.children[v]
      else:
        return -1
    return ans


class Solution:
  def maximizeXor(self, nums: List[int], queries: List[List[int]]) -> List[int]:
    trie = Trie()
    nums.sort()
    j, n = 0, len(queries)
    ans = [-1] * n
    for i, (x, m) in sorted(zip(range(n), queries), key=lambda x: x[1][1]):
      while j < len(nums) and nums[j] <= m:
        trie.insert(nums[j])
        j += 1
      ans[i] = trie.search(x)
    return ans
class Trie {
  private Trie[] children = new Trie[2];

  public void insert(int x) {
    Trie node = this;
    for (int i = 30; i >= 0; --i) {
      int v = x >> i & 1;
      if (node.children[v] == null) {
        node.children[v] = new Trie();
      }
      node = node.children[v];
    }
  }

  public int search(int x) {
    Trie node = this;
    int ans = 0;
    for (int i = 30; i >= 0; --i) {
      int v = x >> i & 1;
      if (node.children[v ^ 1] != null) {
        ans |= 1 << i;
        node = node.children[v ^ 1];
      } else if (node.children[v] != null) {
        node = node.children[v];
      } else {
        return -1;
      }
    }
    return ans;
  }
}

class Solution {
  public int[] maximizeXor(int[] nums, int[][] queries) {
    Arrays.sort(nums);
    int n = queries.length;
    Integer[] idx = new Integer[n];
    for (int i = 0; i < n; ++i) {
      idx[i] = i;
    }
    Arrays.sort(idx, (i, j) -> queries[i][1] - queries[j][1]);
    int[] ans = new int[n];
    Trie trie = new Trie();
    int j = 0;
    for (int i : idx) {
      int x = queries[i][0], m = queries[i][1];
      while (j < nums.length && nums[j] <= m) {
        trie.insert(nums[j++]);
      }
      ans[i] = trie.search(x);
    }
    return ans;
  }
}
class Trie {
private:
  Trie* children[2];

public:
  Trie()
    : children{nullptr, nullptr} {}

  void insert(int x) {
    Trie* node = this;
    for (int i = 30; ~i; --i) {
      int v = (x >> i) & 1;
      if (!node->children[v]) {
        node->children[v] = new Trie();
      }
      node = node->children[v];
    }
  }

  int search(int x) {
    Trie* node = this;
    int ans = 0;
    for (int i = 30; ~i; --i) {
      int v = (x >> i) & 1;
      if (node->children[v ^ 1]) {
        ans |= 1 << i;
        node = node->children[v ^ 1];
      } else if (node->children[v]) {
        node = node->children[v];
      } else {
        return -1;
      }
    }
    return ans;
  }
};

class Solution {
public:
  vector<int> maximizeXor(vector<int>& nums, vector<vector<int>>& queries) {
    sort(nums.begin(), nums.end());
    int n = queries.size();
    vector<int> idx(n);
    iota(idx.begin(), idx.end(), 0);
    sort(idx.begin(), idx.end(), [&](int i, int j) { return queries[i][1] < queries[j][1]; });
    vector<int> ans(n);
    Trie trie;
    int j = 0;
    for (int i : idx) {
      int x = queries[i][0], m = queries[i][1];
      while (j < nums.size() && nums[j] <= m) {
        trie.insert(nums[j++]);
      }
      ans[i] = trie.search(x);
    }
    return ans;
  }
};
type Trie struct {
  children [2]*Trie
}

func NewTrie() *Trie {
  return &Trie{}
}

func (t *Trie) insert(x int) {
  node := t
  for i := 30; i >= 0; i-- {
    v := x >> i & 1
    if node.children[v] == nil {
      node.children[v] = NewTrie()
    }
    node = node.children[v]
  }
}

func (t *Trie) search(x int) int {
  node := t
  ans := 0
  for i := 30; i >= 0; i-- {
    v := x >> i & 1
    if node.children[v^1] != nil {
      ans |= 1 << i
      node = node.children[v^1]
    } else if node.children[v] != nil {
      node = node.children[v]
    } else {
      return -1
    }
  }
  return ans
}

func maximizeXor(nums []int, queries [][]int) []int {
  sort.Ints(nums)
  n := len(queries)
  idx := make([]int, n)
  for i := 0; i < n; i++ {
    idx[i] = i
  }
  sort.Slice(idx, func(i, j int) bool {
    return queries[idx[i]][1] < queries[idx[j]][1]
  })
  ans := make([]int, n)
  trie := NewTrie()
  j := 0
  for _, i := range idx {
    x, m := queries[i][0], queries[i][1]
    for j < len(nums) && nums[j] <= m {
      trie.insert(nums[j])
      j++
    }
    ans[i] = trie.search(x)
  }
  return ans
}
class Trie {
  children: (Trie | null)[];

  constructor() {
    this.children = [null, null];
  }

  insert(x: number): void {
    let node: Trie | null = this;
    for (let i = 30; ~i; i--) {
      const v = (x >> i) & 1;
      if (node.children[v] === null) {
        node.children[v] = new Trie();
      }
      node = node.children[v] as Trie;
    }
  }

  search(x: number): number {
    let node: Trie | null = this;
    let ans = 0;
    for (let i = 30; ~i; i--) {
      const v = (x >> i) & 1;
      if (node.children[v ^ 1] !== null) {
        ans |= 1 << i;
        node = node.children[v ^ 1] as Trie;
      } else if (node.children[v] !== null) {
        node = node.children[v] as Trie;
      } else {
        return -1;
      }
    }
    return ans;
  }
}

function maximizeXor(nums: number[], queries: number[][]): number[] {
  nums.sort((a, b) => a - b);
  const n = queries.length;
  const idx = Array.from({ length: n }, (_, i) => i);
  idx.sort((i, j) => queries[i][1] - queries[j][1]);
  const ans: number[] = [];
  const trie = new Trie();
  let j = 0;
  for (const i of idx) {
    const x = queries[i][0];
    const m = queries[i][1];
    while (j < nums.length && nums[j] <= m) {
      trie.insert(nums[j++]);
    }
    ans[i] = trie.search(x);
  }
  return ans;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文