32ms, O(k*log(k) time complexity, used inner class to simplify things and created a custom comparator for it.

Explanation: Basically, we create a priorityqueue which will sort the inserted elements based on lowest matrix[][] value. At first, we insert the smallest value which is at matrix[0][0]. To iteratively find the next smallest element, we need to take out the smallest value from the priorityqueue, and add the value toward its right / bottom(if we are at the first row) into the priorityqueue (as long as they are within range). The next smallest value must be either already inside the priorityqueue, or be to the right/bottom of the current smallest value. Either way, the priorityqueue will make the correct ordering so that the next smallest value is ready to be removed. We do this loop k-1 times, and remove the kth smallest from the priorityqueue in the end.

```
public class Solution {
public class Point {
int val;
int x;
int y;
public Point(int val, int x, int y) {
this.val = val;
this.x = x;
this.y = y;
}
}
public int kthSmallest(int[][] matrix, int k) {
if(matrix.length == 0) return 0;
PriorityQueue<Point> pq = new PriorityQueue<Point>(new Comparator<Point>(){
@Override
public int compare(Point a, Point b) {
return a.val - b.val;
}
});
pq.offer(new Point(matrix[0][0], 0, 0));
for(int i = 1; i < k; i++) {
Point p = pq.poll();
if((p.x+1) < matrix.length) {
pq.offer(new Point(matrix[p.x+1][p.y], p.x+1, p.y));
}
if(p.x == 0 && (p.y+1) < matrix.length) {
pq.offer(new Point(matrix[p.x][p.y+1], p.x, p.y+1));
}
}
return pq.poll().val;
}
}
```