1是第一层,斜着的3,5是第二层,再斜着的4,7,7是第三层,8,8是第四层, 9是最后一层。
利用方向数组进行向下和向右搜索,利用visited数组记录访问过的位置(可以用hashset,如x*103 + y),minheap移除的都是较小的那个。
Time Complexity: O(klog(min(m,n,k))),队列最大长度是最长的那个对角线的元素个数,which is 行和列长度的更小者(如:很高或者很宽的矩阵);还有一点是当k比行和列长度的更小者小时,队列的最大长度其实是k。
Space Complexity: O(min(m,n,k) + mn),visited数组和pq的大小
Code
publicclassSolution { /** * @param matrix: a matrix of integers * @param k: An integer * @return: the kth smallest number in the matrix */privatestaticclassNode {int x, y, val;publicNode(int x,int y,int val) {this.x= x;this.y= y;this.val= val; } }privatefinalint[][] DIR =newint[][]{{1,0}, {0,1}}; publicintkthSmallest(int[][] matrix,int k) {// write your code hereif (matrix ==null||matrix.length==0|| matrix[0] ==null|| matrix[0].length==0|| k <=0) {thrownewIllegalArgumentException(); }int m =matrix.length, n = matrix[0].length;boolean[][] visited =newboolean[m][n];Queue<Node> pq =newPriorityQueue<>((a,b) ->a.val-b.val);pq.offer(newNode(0,0, matrix[0][0]));for (int i =0; i < k -1; i++) {Node curr =pq.poll();for (int dir =0; dir <2; dir++) {int x =curr.x+DIR[dir][0];int y =curr.y+DIR[dir][1];if (x < m && y < n &&!visited[x][y]) { visited[x][y] =true;pq.offer(newNode(x, y, matrix[x][y])); } } }returnpq.poll().val; }}