找出第 K 大的异或坐标值--力扣

Posted 穿迷彩服的鲨鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了找出第 K 大的异或坐标值--力扣相关的知识,希望对你有一定的参考价值。


前言

给你一个二维矩阵 matrix 和一个整数 k ,矩阵大小为 m x n 由非负整数组成。
矩阵中坐标 (a, b) 的 值 可由对所有满足 0 <= i <= a < m 且 0 <= j <= b < n 的元素 matrix[i][j](下标从 0 开始计数)执行异或运算得到。
请你找出 matrix 的所有坐标中第 k 大的值(k 的值从 1 开始计数)。


一、示例

示例 1:

输入:matrix = [[5,2],[1,6]], k = 1
输出:7
解释:坐标 (0,1) 的值是 5 XOR 2 = 7 ,为最大的值。
示例 2:

输入:matrix = [[5,2],[1,6]], k = 2
输出:5
解释:坐标 (0,0) 的值是 5 = 5 ,为第 2 大的值。
示例 3:

输入:matrix = [[5,2],[1,6]], k = 3
输出:4
解释:坐标 (1,0) 的值是 5 XOR 1 = 4 ,为第 3 大的值。
示例 4:

输入:matrix = [[5,2],[1,6]], k = 4
输出:0
解释:坐标 (1,1) 的值是 5 XOR 2 XOR 1 XOR 6 = 0 ,为第 4 大的值。

二、代码解析

1.二维前缀和 + 排序

代码如下(示例):

	/// <summary>
	/// 二维前缀和 + 排序
	/// </summary>
	/// <param name="matrix"></param>
	/// <param name="k"></param>
	/// <returns></returns>
int kthLargestValue(vector<vector<int>>& matrix, int k)
{
	int m = matrix.size(), n = matrix[0].size();
	vector<vector<int>> newMatrix(m, vector<int>(n, 0));//塑造一个同大小的二维数组
	vector<int> res;
	//计算二位前缀和
	//因数组大小缘故,需要判断是否为第一排或第一列
	for (int i = 0; i < m; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			if (i == 0 && j != 0)//第一排
			{
				newMatrix[i][j] = newMatrix[i][j - 1] ^ matrix[i][j];
			}
			else if (i != 0 && j == 0)//第一列
			{
				newMatrix[i][j] = newMatrix[i - 1][j] ^ matrix[i][j];
			}
			else if (i == 0 && j == 0)//第一排和第一列
			{
				newMatrix[i][j] = matrix[i][j];
			}
			else//其他
			{
				newMatrix[i][j] = newMatrix[i][j - 1] ^ newMatrix[i - 1][j] ^ newMatrix[i - 1][j - 1] ^ matrix[i][j];
			}
			res.emplace_back(newMatrix[i][j]);
		}
	}

	sort(res.begin(), res.end());

	return res[res.size() - k];
}

结果

在这里插入图片描述

2.二维前缀和 + 排序(优化)

代码如下(示例):

/// <summary>
/// 二维前缀和 + 排序
/// </summary>
/// <param name="matrix"></param>
/// <param name="k"></param>
/// <returns></returns>
int kthLargestValue(vector<vector<int>>& matrix, int k)
{
	int m = matrix.size(), n = matrix[0].size();
	vector<vector<int>> newMatrix(m + 1, vector<int>(n + 1, 0));
	vector<int> res;
	/*在二维前缀和的计算过程中,如果我们正在计算首行或者首列,即i=0 或 j=0,
	* 此时例如newMatrix(i-1,j-1) 是一个超出下标范围的结果。
	* 因此我们可以使用一个 (m+1)×(n+1) 的二维矩阵,将首行和首列空出来赋予默认值 0,
	* 并使用接下来的 m 行和 n 列存储二维前缀和,这样就不必进行下标范围的判断了。*/
	for (int i = 1; i <= m; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			newMatrix[i][j] = newMatrix[i][j - 1] ^ newMatrix[i - 1][j] ^ newMatrix[i - 1][j - 1] ^ matrix[i - 1][j - 1];
			res.emplace_back(newMatrix[i][j]);
		}
	}


	sort(res.begin(), res.end());

	return res[res.size() - k];
}

结果

在这里插入图片描述

3.测试

代码如下(示例):

#include<vector>
#include<algorithm>
#include <iostream>
using namespace std;

/// <summary>
/// 二维前缀和 + 排序
/// </summary>
/// <param name="matrix"></param>
/// <param name="k"></param>
/// <returns></returns>
int kthLargestValue(vector<vector<int>>& matrix, int k)
{
	int m = matrix.size(), n = matrix[0].size();
	vector<vector<int>> newMatrix(m + 1, vector<int>(n + 1, 0));
	vector<int> res;
	
	/*for (int i = 0; i < m; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			if (i == 0 && j != 0)
			{
				newMatrix[i][j] = newMatrix[i][j - 1] ^ matrix[i][j];
			}
			else if (i != 0 && j == 0)
			{
				newMatrix[i][j] = newMatrix[i - 1][j] ^ matrix[i][j];
			}
			else if (i == 0 && j == 0)
			{
				newMatrix[i][j] = matrix[i][j];
			}
			else
			{
				newMatrix[i][j] = newMatrix[i][j - 1] ^ newMatrix[i - 1][j] ^ newMatrix[i - 1][j - 1] ^ matrix[i][j];
			}
			res.emplace_back(newMatrix[i][j]);
		}
	}*/
	//优化
	/*在二维前缀和的计算过程中,如果我们正在计算首行或者首列,即i=0 或 j=0,
	* 此时例如newMatrix(i-1,j-1) 是一个超出下标范围的结果。
	* 因此我们可以使用一个 (m+1)×(n+1) 的二维矩阵,将首行和首列空出来赋予默认值 0,
	* 并使用接下来的 m 行和 n 列存储二维前缀和,这样就不必进行下标范围的判断了。*/
	for (int i = 1; i <= m; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			newMatrix[i][j] = newMatrix[i][j - 1] ^ newMatrix[i - 1][j] ^ newMatrix[i - 1][j - 1] ^ matrix[i - 1][j - 1];
			res.emplace_back(newMatrix[i][j]);
		}
	}
	

	sort(res.begin(), res.end());

	return res[res.size() - k];
}

int main()
{
	vector<vector<int>> matrix =
	{
		{8,10,5,8,5,7,6,0,1,4,10,6,4,3,6,8,7,9,4,2}
	};
	cout << kthLargestValue(matrix, 2);
	return 0;
}

结果

在这里插入图片描述


总结

在这里插入图片描述

以上是关于找出第 K 大的异或坐标值--力扣的主要内容,如果未能解决你的问题,请参考以下文章

LC.1738. 找出第 K 大的异或坐标值

1738. 找出第 K 大的异或坐标值

leetcode 1738. 找出第 K 大的异或坐标值

leetcode 1738. 找出第 K 大的异或坐标值

leetcode1738. 找出第 K 大的异或坐标值

LeetCode 1738. 找出第 K 大的异或坐标值(Java动态规划)