Link: https://leetcode.com/problems/diagonal-traverse/
Solution 1:
矩阵最外围的数字是每一次traverse slices的head
偶数位的traverse方向是up right
奇数位的方向是down left
重点是要找到最外围数字的遍历方法
class Solution {
public int[] findDiagonalOrder(int[][] matrix) {
if(matrix.length == 0 || matrix[0].length == 0){
return new int[0];
}
int rows = matrix.length;
int cols = matrix[0].length;
int r,c;
int scan = rows+cols-1; // head of slices
int index = 0;
int[] res = new int[rows*cols];
for(int i=0; i<scan; i++){
if(i%2 == 0){ // up right
// 矩阵的左边和下边
r = i < rows ? i : rows - 1;
c = i < rows ? 0 : i - (rows - 1);
while(r >= 0 && c < cols){
res[index++] = matrix[r--][c++];
}
}else{ // down left
// head在矩阵的上边和右边
r = i < cols ? 0 : i - (cols - 1);
c = i < cols ? i : cols - 1;
while(r < rows && c >= 0){
res[index++] = matrix[r++][c--];
}
}
}
return res;
}
}
TC: O(rows * cols)
SC: O(1) (没有使用extra space)
Solution 2:
统一使用up-right对矩阵进行遍历,将slice暂存在list中,偶数位直接存入res,奇数位reserve后存入
class Solution {
public int[] findDiagonalOrder(int[][] matrix) {
if(matrix.length == 0 || matrix[0].length == 0){
return new int[0];
}
int rows = matrix.length;
int cols = matrix[0].length;
int r,c;
int scan = rows+cols-1; // head of slices
int index = 0;
int[] res = new int[rows*cols];
// 全体up right的方式遍历,奇数列倒序存入res
List<Integer> temp = new ArrayList<>();
for(int i=0; i<scan; i++){
// 遍历左边和下边, 统一用up right的方式存入temp
// 每一次遍历后temp内的数字都要清空
temp.clear();
r = i < rows ? i : rows - 1;
c = i < rows ? 0 : i - (rows - 1);
while(r >= 0 && c < cols){
temp.add(matrix[r--][c++]);
}
if(i%2 == 0){
for(int j=0; j<temp.size(); j++){
res[index++] = temp.get(j);
}
} else {
for(int j=temp.size()-1; j>=0; j--){
res[index++] = temp.get(j);
}
}
}
return res;
}
}
TC: O(rows * cols)
SC: O(min(rows, cols)) (temp存储的最长个数)
方法二TC复杂度不如方法一:
- 在reverse奇数slice的时候会touch每个数字两次
- 在每次清空temp的时候还会用到O(temp.size())的时间