【LeetCode日記】1260. 二維網格遷移

題目地址(1260. 二維網格遷移)

https://leetcode-cn.com/probl...python

題目描述

給你一個 n 行 m 列的二維網格 grid 和一個整數 k。你須要將 grid 遷移 k 次。

每次「遷移」操做將會引起下述活動:

位於 grid[i][j] 的元素將會移動到 grid[i][j + 1]。
位於 grid[i][m - 1] 的元素將會移動到 grid[i + 1][0]。
位於 grid[n - 1][m - 1] 的元素將會移動到 grid[0][0]。
請你返回 k 次遷移操做後最終獲得的 二維網格。

 

示例 1:



輸入:grid = [[1,2,3],[4,5,6],[7,8,9]], k = 1
輸出:[[9,1,2],[3,4,5],[6,7,8]]
示例 2:



輸入:grid = [[3,8,1,9],[19,7,2,5],[4,6,11,10],[12,0,21,13]], k = 4
輸出:[[12,0,21,13],[3,8,1,9],[19,7,2,5],[4,6,11,10]]
示例 3:

輸入:grid = [[1,2,3],[4,5,6],[7,8,9]], k = 9
輸出:[[1,2,3],[4,5,6],[7,8,9]]
 

提示:

1 <= grid.length <= 50
1 <= grid[i].length <= 50
-1000 <= grid[i][j] <= 1000
0 <= k <= 100

暴力法

咱們直接翻譯題目,沒有任何 hack 的作法。算法

代碼

from copy import deepcopy

class Solution:
    def shiftGrid(self, grid: List[List[int]], k: int) -> List[List[int]]:
        n = len(grid)
        m = len(grid[0])
        for _ in range(k):
            old = deepcopy(grid)
            for i in range(n):
                for j in range(m):
                    if j == m - 1:
                            grid[(i + 1) % n][0] = old[i][j]
                    elif i == n - 1 and j == m - 1:
                        grid[0][0] = old[i][j]
                    else:
                        grid[i][j + 1] = old[i][j]
        return grid

因爲是 easy,上述作法勉強能夠過,咱們考慮優化。數組

數學分析

思路

咱們仔細觀察矩陣會發現,其實這樣的矩陣遷移是有規律的。 如圖:
imageapp

所以這個問題就轉化爲咱們一直的一維矩陣轉移問題,LeetCode 也有原題189. 旋轉數組,同時我也寫了一篇文章文科生都能看懂的循環移位算法專門討論這個,最終咱們使用的是三次旋轉法,相關數學證實也有寫,很詳細,這裏再也不贅述。優化

LeetCode 真的是喜歡換湯不換藥呀 😂spa

代碼

Python 代碼:翻譯

#
# @lc app=leetcode.cn id=1260 lang=python3
#
# [1260] 二維網格遷移
#

# @lc code=start


class Solution:
    def shiftGrid(self, grid: List[List[int]], k: int) -> List[List[int]]:
        n = len(grid)
        m = len(grid[0])
        # 二維到一維
        arr = [grid[i][j] for i in range(n) for j in range(m)]
        # 取模,縮小k的範圍,避免無心義的運算
        k %= m * n
        res = []
        # 首尾交換法

        def reverse(l, r):
            while l < r:
                t = arr[l]
                arr[l] = arr[r]
                arr[r] = t
                l += 1
                r -= 1
        # 三次旋轉
        reverse(0, m * n - k - 1)
        reverse(m * n - k, m * n - 1)
        reverse(0, m * n - 1)
        # 一維到二維
        row = []
        for i in range(m * n):
            if i > 0 and i % m == 0:
                res.append(row)
                row = []
            row.append(arr[i])
        res.append(row)

        return res

# @lc code=end

相關題目

參考

相關文章
相關標籤/搜索