一、Problem
Given a 2D grid of size m x n and an integer k. You need to shift the grid k times.
In one shift operation:
- Element at grid[i][j] moves to grid[i][j + 1].
Element at grid[i][n - 1] moves to grid[i + 1][0].
Element at grid[m - 1][n - 1] moves to grid[0][0].
Return the 2D grid after applying shift operation k times.
Input: grid = [[1,2,3],[4,5,6],[7,8,9]], k = 1
Output: [[9,1,2],[3,4,5],[6,7,8]]
二、Solution
方法一:模擬
比賽時,我真的入坑了,按照題目模擬,還是做的特別慢那種,對於每一次 k:
- 新開一個網格用於存儲每一輪的狀態。
- 先將網格的後面 C-1 列填滿,也就是第 0 列不填。
- 然後開始填第 0 列。
- 最後補上第 0 個格子個最後一個格子的值。
- 最後就是把該狀態交給下一輪循環。
class Solution {
public List<List<Integer>> shiftGrid(int[][] g, int k) {
int R = g.length, C = g[0].length;
while (k-- > 0) {
int[][] a = new int[R][C];
for (int i = 0; i < R; i++)
for (int j = 1; j < C; j++) {
a[i][j] = g[i][j-1];
}
for (int i = 1; i < R; i++)
a[i][0] = g[i-1][C-1];
a[0][0] = g[R-1][C-1];
g = a;
}
List<List<Integer>> ans = new ArrayList<>();
for (int i = 0; i < R; i++) {
ans.add(new LinkedList<>());
for (int j = 0; j < C; j++)
ans.get(i).add(g[i][j]);
}
return ans;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
方法二:雙端隊列
這題純模擬真的很複雜,簡便的方法有二:
- 將二維網格轉爲一維數組,然後進行下標運算。
- 使用雙端隊列存儲順序存儲所有元素,然後將隊尾元素添加到隊頭,重複 次
class Solution {
public List<List<Integer>> shiftGrid(int[][] g, int k) {
int R = g.length, C = g[0].length, a[][] = new int[R][C];
Deque<Integer> q = new ArrayDeque<>();
for (int i = 0; i < R; i++)
for (int j = 0; j < C; j++)
q.add(g[i][j]);
while (k-- > 0) {
int back = q.pollLast();
q.addFirst(back);
}
List<List<Integer>> ans = new ArrayList<>();
for (int i = 0; i < R; i++)
ans.add(new LinkedList<>());
for (int i = 0; i < R; i++)
for (int j = 0; j < C; j++) {
g[i][j] = q.poll();
}
for (int i = 0; i < R; i++)
for (int j = 0; j < C; j++) {
ans.get(i).add(g[i][j]);
}
return ans;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,