题目地址:
https://leetcode.com/problems/diagonal-traverse-ii/
给定一个list of list,每个list里都是整数。要求按照这样的顺序遍历:先将矩阵中的数按照横纵坐标之和是多少来分类,按照和小到和大的进行遍历。和相等的数中,按照从左下到右上的顺序进行遍历。题目保证每一个list都非空。
法1:排序 + 汇总。先将所有的坐标存起来,然后对其进行排序,先按照横纵坐标和进行排序,如果相等,则按照 x x x坐标由大到小排序。然后再把结果汇总。代码如下:
import java.util.ArrayList;
import java.util.List;
public class Solution {
class Pair {
int x, y;
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
}
public int[] findDiagonalOrder(List<List<Integer>> nums) {
List<Pair> list = new ArrayList<>();
for (int i = 0; i < nums.size(); i++) {
for (int j = 0; j < nums.get(i).size(); j++) {
list.add(new Pair(i, j));
}
}
list.sort((o1, o2) -> {
int s1 = o1.x + o1.y, s2 = o2.x + o2.y;
if (s1 != s2) {
return Integer.compare(s1, s2);
}
return -Integer.compare(o1.x, o2.x);
});
int[] res = new int[list.size()];
for (int i = 0; i < res.length; i++) {
Pair pair = list.get(i);
res[i] = nums.get(pair.x).get(pair.y);
}
return res;
}
}
时间复杂度 O ( n log n ) O(n\log n) O(nlogn),空间 O ( n ) O(n) O(n), n n n为总共数字的数量。
法2:BFS。相当于从左上角向右下角做BFS。代码如下:
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class Solution {
public int[] findDiagonalOrder(List<List<Integer>> nums) {
int count = 0;
for (List<Integer> list : nums) {
count += list.size();
}
// 初始化答案
int[] res = new int[count];
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{0, 0});
int idx = 0;
while (!queue.isEmpty()) {
int[] cur = queue.poll();
res[idx++] = nums.get(cur[0]).get(cur[1]);
if (cur[0] + 1 < nums.size() && cur[1] == 0) {
queue.offer(new int[]{cur[0] + 1, 0});
}
if (cur[1] + 1 < nums.get(cur[0]).size()) {
queue.offer(new int[]{cur[0], cur[1] + 1});
}
}
return res;
}
}
时空复杂度 O ( n ) O(n) O(n), n n n为总共数字的数量。