1. 程式人生 > 實用技巧 >劍指 Offer 29. 順時針列印矩陣

劍指 Offer 29. 順時針列印矩陣

劍指 Offer 29. 順時針列印矩陣

迴圈列印二維陣列/矩陣的規律:

從左向右列印,此時上邊界向下移動,行不變,列++

從上向下列印,此時右界向左移動,列不變,行++

從右向左列印,此時下邊界向上移動,行不變,列--

從下向上列印,此時上左界向右移動,列不變,行--

演算法框架

int t=0,b=m-1,l=0,r=n-1;
while(true){
	//從左向右列印,此時上邊界向下移動,行不變,列++
    for(int i=l;i<=r;i++){
        num[top][i];
    }
    t++;
    if(t>b) break;
    
    //從上向下列印,此時右界向左移動,列不變,行++
    for(int i=t;i<=b;i++){
        num[i][r];
    }
    r--;
    if(l>r) break;
    
    //從右向左列印,此時下邊界向上移動,行不變,列--
    for(int i=r;i>=l;i-){
        num[b][i];
    }
    b--;
    if(t>b) break;
    //從下向上列印,此時上左界向右移動,列不變,行--
    for(int i=b;i>=t;i--){
        num[i][l];
    }
    l++;
    if(l>r) break;
}

實現

public int[] spiralOrder(int[][] matrix) {
    if(matrix.length == 0){
        return new int[]{};
    }   
    List<Integer> list = new ArrayList<>();

    int top = 0;
    int bottom = matrix.length-1;
    int left = 0;
    int right = matrix[0].length-1;
    while(true) {
        //從左向右打
        for(int i=left;i<=right;i++) {
            list.add(matrix[top][i]);
        }
        if(++top>bottom) {
            break;
        }
        //從上到下
        for(int i=top;i<=bottom;i++) {
            list.add(matrix[i][right]);
        }
        if(left>--right) {
            break;
        }
        //從右到左
        for(int i=right;i>=left;i--) {
            list.add(matrix[bottom][i]);
        }
        if(top>--bottom) {
            break;
        }
        //從下到上
        for(int i=bottom;i>=top;i--) {
            list.add(matrix[i][left]);
        }
        if(++left>right) {
            break;
        }
    }
    return list.stream().mapToInt(Integer::valueOf).toArray();
}