排序矩陣的定義爲:每一行遞增,每一列也遞增。
樣例
給出 k = 4 和一個排序矩陣:
[
[1 ,5 ,7],
[3 ,7 ,8],
[4 ,8 ,9],
]
返回 5。
挑戰
使用O(k log n)的方法,n爲矩陣的寬度和高度中的最大值。
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;
/**
* 在一個排序矩陣中找從小到大的第 k 個整數。
排序矩陣的定義爲:每一行遞增,每一列也遞增。
樣例
給出 k = 4 和一個排序矩陣:
[
[1 ,5 ,7],
[3 ,7 ,8],
[4 ,8 ,9],
]
返回 5。
挑戰
使用O(k log n)的方法,n爲矩陣的寬度和高度中的最大值。
*
* @author Dell
*
*/
class Node{
public int x;
public int y;
public int val;
public Node(int x, int y, int val)
{
this.x=x;
this.y=y;
this.val=val;
}
}
public class Test401 {
//直接放入優先隊列,此方法沒有利用矩陣是排序的特點,時間複雜度O(m*n),所以超時
public static int kthSmallest1(int[][] matrix,int k)
{
int m=matrix.length;
int n=matrix[0].length;
if(k<0||k>m*n)
return 0;
int result=0;
PriorityQueue<Integer> p=new PriorityQueue<>();
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
p.offer(matrix[i][j]);
}
}
for(int i=0;i<k;i++)
{
if(i==k-1)
result=p.poll();
p.poll();
}
return result;
}
public static int kthSmallest2(int[][] matrix, int k)
{
int m =matrix.length;
if(m==0)
return 0;
int n=matrix[0].length;
boolean[][] hash=new boolean[m][n];
int[] dx=new int[]{0,1};
int[] dy=new int[]{1,0};
PriorityQueue<Node> q=new PriorityQueue<Node>(new Comparator<Node>(){
@Override
public int compare(Node o1, Node o2) {
return o1.val-o2.val;
}
});
q.offer(new Node(0,0,matrix[0][0]));
hash[0][0]=true;
for(int i=0;i<k-1;i++)
{
Node temp=q.poll();
for(int j=0;j<2;j++)
{
int new_x=temp.x+dx[j];
int new_y=temp.y+dy[j];
Node temp1=new Node(new_x,new_y,0);
if(new_x<m&&new_y<n&&hash[new_x][new_y]==false)
{
hash[new_x][new_y]=true;
temp1.val=matrix[new_x][new_y];
q.offer(temp1);
}
}
}
return q.peek().val;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int m=sc.nextInt();
int n=sc.nextInt();
int[][] a=new int[m][n];
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
a[i][j]=sc.nextInt();
}
}
int k=sc.nextInt();
System.out.println(kthSmallest2(a,k));
}
}