赞
踩
- Given a nxn matrix where each of the rows and columns are sorted in ascending order,
- find the kth smallest element in the matrix.
- Note that it is the kth smallest element in the sorted order,not the kth distinct element.
- Example 1:
- Input:matrix=[[1,5,9],
- [10,11,13],
- [12,13,15]],k=8
- Output:13
- Note:You may assume k is always valid,1<=k<=n2.
- 题目大意:
- 给定一个nxn矩阵,其中每行每列元素都是按照升序进行排序,找出矩阵中第k小的元素.注意它是排序后的第k个小元素,而不是
- 第k个元素.
- 说明:你可以假设k的值永远是有效的,1<=k<=n2.
-
- 解题思路:
- 这道题想到的是优先队列,依次把矩阵中的元素推入到优先队列中,维护一个最小堆,一旦优先队列中里面有k个元素,则找到了
- 答案.
- 最优解是二分查找,从矩阵可以看出左上角的那个元素是最小的,右上角的元素是最大的.在这个解空间里面二分搜索所有值,找到
- 第k小的元素.判断是否找到的条件是,在矩阵中比mid小的元素个数等于k.不断的逼近low,使得low==high的时候,就是找到
- 了最k小的元素.
-
- 根据题例,作如下分析:
- Example :
- [[2,6,8],
- [3,7,10],
- [5,8,11]],k=5
- Step1:
- middle=(start+end)/2=(2+11)/2=6
- smallest number greater than the middle(6):7
- biggest number less than or equal to the middle(6):6
- number of elements less than or equal to the middle(6)=4
- As there are only 4 elements less than or equal to the middle,and we are looking for 5th
- smallest number,so let's search higher and update our 'start' to the smallest number
- greater than the middle.
- Step2:
- middle=(start+end)/2=(7+11)/2=9
- smallest number greater than the middle(9):10
- biggest number less than or equal to the middle(9):8
- number of elements less than or equal to the middle(9)=7
- As there are only 7 elements less than or equal to the middle,and we are looking for 5th
- smallest number,so let's search lower and update our 'end' to the biggest number
- less than or equal to the middle.
-
- Step3:
- middle=(start+end)/2=(7+8)/2=7
- smallest number greater than the middle(7):8
- biggest number less than or equal to the middle(7):8
- number of elements less than or equal to the middle(7)=5
- As there are only 5 elements less than or equal to the middle therefore '7',which is the
- biggest number less than or equal to the middle,is our required number.
- package main
-
- import (
- "container/heap"
- "fmt"
- )
-
- /*二分搜索*/
- func kthSmallest(matrix [][]int,k int)int{
- m,n,low:=len(matrix),len(matrix[0]),matrix[0][0]
- high,mid:=matrix[m-1][n-1],0
- for low<high{
- mid=low+(high-low)>>1
- /*若count比k小,则在大值的那一半继续二分查找*/
- if counterKthSmall(m,n,mid,matrix)>=k{
- high=mid
- }else{
- low=mid+1
- }
- }
- return low
- }
-
- func counterKthSmall(m,n,mid int,matrix [][]int)int{
- count,j:=0,n-1
- /*每次循环统计比mid值小的元素个数*/
- for i:=0;i<m;i++{
- for j>=0&&mid<matrix[i][j]{
- j--/*遍历每行中比mid小的元素的个数*/
- }
- count+=j+1
- }
- return count
- }
-
- /*优先队列*/
- func kthSmallest1(matrix [][]int,k int)int{
- if len(matrix)==0||len(matrix[0])==0{return 0}
- pq:=&pq{data:make([]interface{},k)}
- heap.Init(pq)
- for i:=0;i<len(matrix);i++{
- for j:=0;j<len(matrix[0]);j++{
- if pq.Len()<k{
- heap.Push(pq,matrix[i][j])
- }else if matrix[i][j]<pq.Head().(int){
- heap.Pop(pq)
- heap.Push(pq,matrix[i][j])
- }else{
- break
- }
- }
- }
- return heap.Pop(pq).(int)
- }
-
- type pq struct{
- data []interface{}
- len int
- }
-
- func (p *pq) Len()int{
- return p.len
- }
-
- func (p *pq) Less(a,b int) bool{
- return p.data[a].(int)>p.data[b].(int)
- }
-
- func (p *pq) Swap(a,b int){
- p.data[a],p.data[b]=p.data[b],p.data[a]
- }
-
- func (p *pq) Push(o interface{}){
- p.data[p.len]=o
- p.len++
- }
-
- func (p *pq) Head()interface{}{
- return p.data[0]
- }
-
- func (p *pq) Pop()interface{}{
- p.len--
- return p.data[p.len]
- }
- func main(){
- matrix:=[][]int{{1,5,9},{10,11,13},{12,13,15}}
- fmt.Println(kthSmallest1(matrix,8))
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。