python n个list如何组成矩阵_有序矩阵中第K小的元素amp;x的平方根(二分法篇)
69. x的平方根
题目描述:
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例1:
输入: 4
输出: 2
示例2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。
题解: 二分法
一个数的平方根不会超过它本身的一半。根据(a/2)^2 >=a,求得a>=4或者a<=0,于是边界值为4。对于0,1,2,3,其平方根分别为0,1,1,1。
public class Solution { public int mySqrt(int x) { // 注意:针对特殊测试用例,例如 2147395599 // 要把搜索的范围设置成长整型 // 为了照顾到 0 把左边界设置为 0 long left = 0; // # 为了照顾到 1 把右边界设置为 x // 2 + 1 long right = x / 2 + 1; while (left < right) { // 注意:这里一定取右中位数,如果取左中位数,代码会进入死循环 // long mid = left + (right - left + 1) / 2; long mid = (left + right + 1) >>> 1; long square = mid * mid; if (square > x) { right = mid - 1; } else { left = mid; } } // 因为一定存在,因此无需后处理 return (int) left; }}
注意:中间值mid声明为int,针对大整型测试用例通不过,因此需要声明为long
378. 有序矩阵中第K小的元素
题目描述:
给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。
请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素。
示例:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
返回 13。
题解1: 二分法
思路:左边界值取矩阵的最小值(左上角元素),右边界取矩阵的最大值(右下角元素),统计矩阵中小于等于mid(最大最小值的均值)的元素个数,用二分法查最小的K个元素。
class Solution {public: int FindNoMoreThanMid(vector<vector<int>>& matrix, int mid,int n){ //查找有序矩阵中某值元素的方法,从左下角开始搜索 int row=n,col=0,count=0; while(row>=0 && col<=n) { if(matrix[row][col]<=mid) { count += row+1; ++col; } else row--; } return count; } int kthSmallest(vector<vector<int>>& matrix, int k) { int n=matrix.size()-1; int left=matrix[0][0],right=matrix[n][n]; while(left { int mid=(left+right)/2; int count=FindNoMoreThanMid(matrix,mid,n); if(count left=mid+1; else right=mid; } return right; }};
题解2: 归并排序
由题知,矩阵的每一行均为一个有序数组,问题转化为从这 N 个有序数组中找第 K 个大的数,利用归并排序,归并到第 K 个数即可停止。
N 个数组归并,需要用小根堆维护
class Solution {public: int kthSmallest(vector<vector<int>>& matrix, int k) { struct point { int val, x, y; point(int val, int x, int y) : val(val), x(x), y(y) {} bool operator> (const point& a) const { return this->val > a.val; } }; priority_queuevector int n = matrix.size(); for (int i = 0; i < n; i++) { que.emplace(matrix[i][0], i, 0); } for (int i = 0; i < k - 1; i++) { point now = que.top(); que.pop(); if (now.y != n - 1) { que.emplace(matrix[now.x][now.y + 1], now.x, now.y + 1); } } return que.top().val; }};
时间复杂度:O(klogN),归并 k 次,每次堆中插入和弹出的操作时间复杂度均为 logN
空间复杂度:O(n),堆的大小始终为 N
思路详解:在整个矩阵中,每次弹出矩阵的最小值,第k个被弹出的就是我们需要的数字。
现在我们的目的很明确:每次弹出矩阵中最小的值。
当我们看到下面这个有序矩阵时,我们知道左上角的数字是整个矩阵最小的,
但弹出它后我们如何保证接下来每一次都还能找到全矩阵最小的值呢?
其实解决这个问题的关键,在于维护一组“最小值候选人”:
你需要保证最小值必然从这组候选人中产生,于是每次只要从候选人中弹出最小的一个即可。
我们来选择第一组候选人,在这里可以选择第一列,因为每一个数字都是其对应行的最小值,全局最小值也必然在其中。
第一次弹出很简单,将左上角的1弹出即可。
1弹出之后,我们如何找到下一个候选人呢?
其实非常简单,刚才弹出的位置右移一格就行了,这样不是还是能保证候选人列表中每一个数字是每一行的最小值吗,那全局最小值必然在其中!
我们每次弹出候选人当中的最小值,然后把上次弹出候选人的右边一个补进来,就能一直保证全局最小值在候选人列表中产生,顺序是每一行都是从左向右看,当某一行弹到没东西,候选人列表的长度就会少1
堆:
父节点>=其子节点,则为大根堆;父节点<=其子节点,则为小根堆;
Python代码:
class Solution: def kthSmallest(self, matrix: List[List[int]], k: int) -> int: n = len(matrix) #注:题目中这个矩阵是n*n的,所以长宽都是n pq = [(matrix[i][0], i, 0) for i in range(n)] #取出第一列候选人 #matrix[i][0]是具体的值,后面的(i,0)是在记录候选人在矩阵中的位置,方便每次右移添加下一个候选人 heapq.heapify(pq) #变成一个heap for i in range(k - 1): #一共弹k次:这里k-1次,return的时候1次 num, x, y = heapq.heappop(pq) #弹出候选人里最小一个 if y != n - 1: #如果这一行还没被弹完 heapq.heappush(pq, (matrix[x][y + 1], x, y + 1)) #加入这一行的下一个候选人 return heapq.heappop(pq)[0]
python n个list如何组成矩阵_有序矩阵中第K小的元素amp;x的平方根(二分法篇)相关推荐
- 【LeetCode】378. 有序矩阵中第 K 小的元素(js 实现)
1.题目:378. 有序矩阵中第 K 小的元素 - 力扣(LeetCode) (leetcode-cn.com) 2.实现 (1)方法一: 直接将矩阵转换为一维数组,再将一维数组进行排序,最后取第k个 ...
- LeetCode 230. Kth Smallest Element in a BST--C++,Python解法--面试真题--找二叉树中第K小的元素
题目地址:Kth Smallest Element in a BST - LeetCode Given a binary search tree, write a function kthSmalle ...
- LeetCode每日训练2—有序矩阵中第K小的元素(7.2)
题目描述 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素. 请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素. 示例: matrix = [ [ ...
- 378. Kth Smallest Element in a Sorted Matrix 有序矩阵中第K小的元素
Title 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素. 请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素. 示例: matrix = [ [ ...
- LeetCode 378. 有序矩阵中第K小的元素(二分查找)
文章目录 1. 题目 2. 解题 2.1 暴力法 2.2 二分查找 1. 题目 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素. 请注意,它是排序后的第k小元素,而 ...
- 378. 有序矩阵中第K小的元素
2020-05-25 1.题目描述 有序矩阵中第K小的元素 2.题解 1.优先队列 2.使用二分查找 class Solution { public:int kthSmallest(vector< ...
- 174. 地下城游戏;剑指 Offer 40. 最小的k个数;378. 有序矩阵中第K小的元素;703. 数据流中的第K大元素
一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主. 骑士的初始 ...
- 力扣第378题 有序矩阵中第K小的元素
题目描述 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素. 请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素. 示例: matrix = [ [ ...
- 378、有序矩阵中第K小的元素
题目:给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素 归并排序 思路及算法 由题目给出的性质可知,这个矩阵的每一行均为一个有序数组.问题即转化为从这 n 个 ...
最新文章
- 苹果裁员逾200人,拿无人驾驶“开刀”
- Java定时器Timer
- 手电筒android studio,Android Studio:手电筒关闭时崩溃
- 学生上课睡觉班主任怎么处理_【师问师答】学生上课说话,点名批评还嘴怎么办?...
- 【面试题22】栈的压入、弹出序列
- 自己闲来无事做的工作日志WEB程序(VB.NET)
- SQLite(二)高级操作
- Citrix基础端口了解
- Excel中的图表制作(一) -各种商品销售量显示
- ES6对比ES3\ES5
- html5中播放本地音乐播放器,首款HTML5播放器 支持浏览器内播放本地音乐
- UI设计必掌握的软件之一:Axure!
- Git使用流程及技巧 - 详细教程
- Outlook-VBA-06-邮件另存为
- 清华大学出版社大数据可视化技术与应用第六章Tableau实训
- 电商营销策略介绍,电商营销手段有哪些
- C语言:链表实现二进制数加1运算
- CreateJS-EaselJS文档翻译
- 2021 ICPC沈阳 J.Luggage Lock(bfs,模拟)
- E01-前端整合:【案例】添加数据页面
热门文章
- DotLucene源码浅读笔记(1) : Lucene.Net.Analysis 【转】
- js入门·对象属性方法大总结
- 2022年计算机408统考大纲,相比往年大量改动
- matlab求奶制品,数学建模案例之线性规划.ppt
- mysql5.6忘记立马_MySQL 5.7 安装完成后,立即要调整的性能选项
- 【连载】如何掌握openGauss数据库核心技术?秘诀四:拿捏事务机制(3)
- MogDB/openGauss 手动部署(非OM工具)单机、主备、主备级联架构
- 快过年了,来,来,来!给七大姑八大姨好好解释解释【啥是DBA 】
- MySQL高可用实现:主从结构下ProxySQL中的读写分离
- 测试用例又双叒叕失败了,NLP帮你