Leetcode Task07:完成54、59、61题目并打卡

054 螺旋矩阵

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]

解法
给出⼀个⼆维数组,按照螺旋的⽅式输出
解法⼀:需要注意的是特殊情况,⽐如⼆维数组退化成⼀维或者⼀列或者⼀个元素。注意了这些情况,基本就可以⼀次通过了。
解法⼆:提前算出⼀共多少个元素,⼀圈⼀圈地遍历矩阵,停⽌条件就是遍历了所有元素(count == sum)

官方解法
绘制螺旋轨迹路径,我们发现当路径超出界限或者进入之前访问过的单元格时,会顺时针旋转方向。

假设数组有R 行 C 列,seen[r,c]表示第 r 行第 c 列的单元格之前已经被访问过了。当前所在位置为(r, c),前进方向是 di。我们希望访问所有R x C 个单元格。

当我们遍历整个矩阵,下一步候选移动位置是(cr, cc)。如果这个候选位置在矩阵范围内并且没有被访问过,那么它将会变成下一步移动的位置;否则,我们将前进方向顺时针旋转之后再计算下一步的移动位置。

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> list = new ArrayList<>();
        if(matrix.length==0){
            return list;
        }
        int rowlen = matrix.length;
        int collen = matrix[0].length;
        int total_num = 0;
        int left = 0;
        int right = collen - 1;
        int top = 0;
        int bottom = rowlen - 1;
        while (total_num != rowlen * collen) {
            for (int i = left; i <= right; i++) {
                list.add(matrix[top][i]);
                total_num++;
            }
            if (total_num == rowlen * collen) break;
            top++;
            for (int i = top; i <= bottom; i++) {
                list.add(matrix[i][right]);
                total_num++;
            }
            if (total_num == rowlen * collen) break;
            right--;
            for (int i = right; i >= left; i--) {
                list.add(matrix[bottom][i]);
                total_num++;
            }
            if (total_num == rowlen * collen) break;
            bottom--;
            for (int i = bottom; i >= top; i--) {
                list.add(matrix[i][left]);
                total_num++;
            }
            if (total_num == rowlen * collen) break;
            left++;
        }
        return list;
    }
}

059 螺旋矩阵 II

Given a positive integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

解题思路
给出⼀个数组 n,要求输出⼀个 n * n 的⼆维数组,⾥⾯元素是 1 - n*n,且数组排列顺序是螺旋排列的

class Solution {
    public int[][] generateMatrix(int n) {
        int l = 0, r = n - 1, t = 0, b = n - 1;
        int[][] mat = new int[n][n];
        int num = 1, tar = n * n;
        while(num <= tar){
            for(int i = l; i <= r; i++) mat[t][i] = num++; // left to right.
            t++;
            for(int i = t; i <= b; i++) mat[i][r] = num++; // top to bottom.
            r--;
            for(int i = r; i >= l; i--) mat[b][i] = num++; // right to left.
            b--;
            for(int i = b; i >= t; i--) mat[i][l] = num++; // bottom to top.
            l++;
        }
        return mat;
    }
}

061 旋转链表

Given a linked list, rotate the list to the right by k places, where k is non-negative.
旋转链表 K 次。
解题思路
这道题需要注意的点是,K 可能很⼤,K = 2000000000 ,如果是循环肯定会超时。应该找出 O(n) 的复杂度的算法才⾏。由于是循环旋转,最终状态其实是确定的,利⽤链表的⻓度取余可以得到链表的最终旋转结果。
这道题也不能⽤递归,递归解法会超时。

class Solution {
  public ListNode rotateRight(ListNode head, int k) {
    // base cases
    if (head == null) return null;
    if (head.next == null) return head;

    // close the linked list into the ring
    ListNode old_tail = head;
    int n;
    for(n = 1; old_tail.next != null; n++)
      old_tail = old_tail.next;
    old_tail.next = head;

    // find new tail : (n - k % n - 1)th node
    // and new head : (n - k % n)th node
    ListNode new_tail = head;
    for (int i = 0; i < n - k % n - 1; i++)
      new_tail = new_tail.next;
    ListNode new_head = new_tail.next;

    // break the ring
    new_tail.next = null;

    return new_head;
  }
}
posted @ 2021-01-18 14:19  Vincy_Lemon  阅读(39)  评论(0)    收藏  举报