ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-05-19 22:32:31  阅读:214  来源: 互联网

标签:matrix int 复杂度 mn 异或 vector leetcode1738 坐标值 sum


目录

题目

给你一个二维矩阵 matrix 和一个整数 k ,矩阵大小为 m x n 由非负整数组成。

矩阵中坐标 (a, b) 的 值 可由对所有满足 0 <= i <= a < m 且 0 <= j <= b < n 的元素 matrix[i][j](下标从 0 开始计数)执行异或运算得到。

请你找出 matrix 的所有坐标中第 k 大的值(k 的值从 1 开始计数)。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-kth-largest-xor-coordinate-value
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

提示:

m == matrix.length
n == matrix[i].length
1 <= m, n <= 1000
0 <= matrix[i][j] <= 106
1 <= k <= m * n

思路

异或轻松搞定。
r[i][j] = r[i-1][j]^r[i][j-1]^r[i-1][j-1]^matrix[i][j]
关键是排序。找第k个。

答案

class Solution {
public:
    int kthLargestValue(vector<vector<int>>& matrix, int k) {
        //r[i][j] = r[i-1][j]^r[i][j-1]^r[i-1][j-1]^matrix[i][j]
        int m = matrix.size();
        int n = matrix[0].size();
        vector<int> compare;
        //r比matric多一行一列
        vector<vector<int>> r(m+1,vector<int>(n+1,0));
        for(int i = 1;i<=m;i++){
            for(int j=1;j<=n;j++){
                r[i][j] = r[i-1][j]^r[i][j-1]^r[i-1][j-1]^matrix[i-1][j-1];
                compare.push_back(r[i][j]);
            }
        }
        sort(compare.begin(),compare.end(),greater());
        return compare[k-1];
    }
};

时间复杂度:O(mnlog(mn))。计算二维前缀和的时间复杂度为 O(mn),排序的时间复杂度为 O(mnlog(mn)),因此总时间复杂度为 O(mnlog(mn))。

空间复杂度:O(mn),即为存储二维前缀和需要的空间。

小tips:
注意二维数组取大小的方式
int m = matrix.size();
int n = matrix[0].size();

改进

1.nth_element()

class Solution {
public:
    int kthLargestValue(vector<vector<int>>& matrix, int k) {
        int m = matrix.size(), n = matrix[0].size();
        vector<vector<int>> pre(m + 1, vector<int>(n + 1));
        vector<int> results;
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                pre[i][j] = pre[i - 1][j] ^ pre[i][j - 1] ^ pre[i - 1][j - 1] ^ matrix[i - 1][j - 1];
                results.push_back(pre[i][j]);
            }
        }

        nth_element(results.begin(), results.begin() + k - 1, results.end(), greater<int>());
        return results[k - 1];
    }
};

时间复杂度:O(mn)。计算二维前缀和的时间复杂度为 O(mn),快速选择找出第 k 大的元素的期望时间复杂度为O(mn),最坏情况下时间复杂度为 O((mn)^2),因此总时间复杂度为 O(mn)。

空间复杂度:O(mn),即为存储二维前缀和需要的空间

std::nth_element

该函数的作用为将迭代器指向的从_First 到 _last 之间的元素进行二分排序,以_Nth 为分界,前面都比 _Nth小(大),后面都比之大(小);但是两段内并不有序。
特别适用于找出前k个最大(最小)的元素。

http://www.cplusplus.com/reference/algorithm/nth_element/?kw=nth_element

2. 优先队列(堆)

class Solution {
public:
    int kthLargestValue(vector<vector<int>>& mat, int k) {
        int m = mat.size(), n = mat[0].size();
        int sum[m+1][n+1];
        memset(sum, 0, sizeof(sum));
        priority_queue<int, vector<int>, greater<int>> pq;
        for(int i = 1; i <= m; i++) {
            for(int j = 1; j <= n; j++) {
                sum[i][j] = sum[i-1][j] ^ sum[i][j-1] ^ sum[i-1][j-1] ^ mat[i-1][j-1];
                if(pq.size() < k)
                    pq.push(sum[i][j]);
                else {
                    if(sum[i][j] > pq.top()) {
                        pq.pop();
                        pq.push(sum[i][j]);
                    }
                }
            }
        }
        return pq.top();
    }
};

//升序队列
priority_queue <int,vector,greater > q;
//降序队列
priority_queue <int,vector,less >q;
//greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)

标签:matrix,int,复杂度,mn,异或,vector,leetcode1738,坐标值,sum
来源: https://blog.csdn.net/weixin_39938635/article/details/117047145

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有