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,上述作法勉強能夠過,咱們考慮優化。數組
咱們仔細觀察矩陣會發現,其實這樣的矩陣遷移是有規律的。 如圖:app
所以這個問題就轉化爲咱們一直的一維矩陣轉移問題,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