1707. 与数组中元素的最大异或值

题目链接:leetcode.

暴力果然是无法通过的

/*
55 / 67 个通过测试用例
*/
class Solution {
public:
    vector<int> maximizeXor(vector<int>& nums, vector<vector<int>>& queries) {
        sort(nums.begin(), nums.end());
        int N = queries.size();
        vector<int> ans(N, 0);
        for(int i = 0;i < N;++i)
        {
            int x = queries[i][0];
            int t = -1;
            for(int j = 0;j < nums.size() && nums[j] <= queries[i][1];++j)
            {
                t = max(t, nums[j] ^ x);
                // cout << t << ' ';
            }
            // cout << endl;
            ans[i] = t;
        }
        return ans;
    }
};

用辅助空间记录queries的索引,然后将其按m值排序
nums也从小到大排序
对于每个查询,插入小于m的所有nums[i],再查询插入后的最大值

/*
执行用时:944 ms, 在所有 C++ 提交中击败了53.99%的用户
内存消耗:275.8 MB, 在所有 C++ 提交中击败了5.23%的用户
*/
class Trie{
	Trie* left; // 1
	Trie* right; // 0
	const int maxL = 30;
	
public:
	Trie() : left(nullptr), right(nullptr) {}
	
	void insert(int num)
	{
		Trie* node = this;
		for(int i = maxL;i >= 0;--i)
		{
			int t = (num >> i) & 1;
			if(t == 1)
			{
				if(node -> left == nullptr)
					node -> left = new Trie();
				node = node -> left;
			}
			else
			{
				if(node -> right == nullptr)
					node -> right = new Trie();
				node = node -> right;
			}
		}
	}
	
	int searchMax(int num)
	{
		Trie* node = this;
		int ans = 0;
		for(int i = maxL;i >= 0;--i)
		{
			int t = (num >> i) & 1;
			if(t == 1)
			{
				//最好找到0
				if(node -> right != nullptr)
				{
					ans |= (1 << i);//该位可以为1 
					node = node -> right; 
				} 
				//找不到的话对应位就是0,也没关系 
				else
				{
					node = node -> left;
				}
			}
			else
			{
				if(node -> left != nullptr)
				{
					ans |= (1 << i);
					node = node -> left;
				}
				else
				{
					node = node -> right;
				}
			}
		}
		return ans;
	} 
}; 
class Solution {
public:
    vector<int> maximizeXor(vector<int>& nums, vector<vector<int>>& queries) {
        sort(nums.begin(), nums.end());
        Trie* root = new Trie();
        int N = queries.size();
        for(int i = 0;i < N;++i)
		{
			queries[i].emplace_back(i);//记录原本的索引 
		} 
		sort(queries.begin(), queries.end(), [&](auto &a, auto &b){
			return a[1] < b[1];
		});
		
		vector<int> ans(N);
		int idx = 0;//nums[i]的索引
		
		for(auto x : queries)
		{
			while(idx < nums.size() && nums[idx] <= x[1])
			{
				root -> insert(nums[idx]);
				idx++;
			}
			if(idx == 0)
			{
				ans[x[2]] = -1;
			}
			else
			{
				ans[x[2]] = root -> searchMax(x[0]);
			}
		} 
		return ans;
    }
};

还可以进行优化,不用额外的排序,在前缀树中记录一个min节点,下次再看呜呜呜

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值