找出第 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 大的异或坐标值--力扣的主要内容,如果未能解决你的问题,请参考以下文章