一、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;
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,