【C/C++】1260. 二维网格迁移

180 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情


题目链接:1260. 二维网格迁移

题目描述

给你一个 mn 列的二维网格 grid 和一个整数 k。你需要将 grid 迁移 k 次。

每次「迁移」操作将会引发下述活动:

  • 位于 grid[i][j] 的元素将会移动到 grid[i][j + 1]
  • 位于 grid[i][n - 1] 的元素将会移动到 grid[i + 1][0]
  • 位于 grid[m - 1][n - 1] 的元素将会移动到 grid[0][0]

请你返回 k 次迁移操作后最终得到的 二维网格

提示:

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

示例 1:

e1-1.png

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

示例 2:

e2-1.png

输入: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]]

整理题意

将二维数组进行「迁移」操作 k 次,对于每一次迁移为将二维数组中的每个整数向右整体移动一格,如果位于二维数组中最后一列的元素则移动至下一行的第一个位置,位于最后一行最后一列的元素移至第一行第一列的位置。按照上述规则移动 k 次,返回将二维数组进行「迁移」操作 k 次后的结果。

解题思路分析

由于题目数据范围较小,采用暴力模拟的方式也是可以通过的(比如队列模拟 k 次「迁移」操作)。

一维展开

根据「迁移」操作的规则我们可以发现,将二维数组每一行按照顺序进行首尾连接形成一个一维数组,那么对于「迁移」操作可以理解为将一维数组进行整体向右循环移动的操作。那么考虑在一维数组中移动前后的位置关系(假设原来的整数在二维数组中的位置为 grid[i][j]):

  • 移动前在展开的一维数组中的位置为:i * m + jm 为二维数组的列数)
  • 移动后在展开的一维数组中的位置为:(i * m + j + k) % (n * m)n 为二维数组的行数,m 为二维数组的列数)
  • 那么再将一维数组转化为 n * m 的二维数组对应的位置为:grid[index / m][index % m]index 的值为在一维数组中移动后的位置:index = (i * m + j + k) % (n * m)

具体实现

  • 遍历二维数组中每个元素;
  • 计算每个元素在一维数组中向右循环移动 k 次后的位置;
  • 再将一维数组转换为二维数组中的位置即可。

复杂度分析

  • 时间复杂度:O(mn)O(mn),其中 m 和 n 分别为网格的行列数。
  • 空间复杂度:O(1)O(1)。返回值不计入空间复杂度。

代码实现

class Solution {
public:
    vector<vector<int>> shiftGrid(vector<vector<int>>& grid, int k) {
        int n = grid.size(), m = grid[0].size();
        vector<vector<int>> res(n, vector<int>(m));
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                int index = (i * m + j + k) % (m * n);
                res[index / m][index % m] = grid[i][j];
            }
        }
        return res;
    }
};

总结

  • 该题的核心思想为 将二维数组转化为一维数组进行循环右移操作,再将一维数组转换为二维数组 即可。
  • 将二维数组转化为一维数组,再将一维数组转换为二维数组的思想不用显性转化,可以通过下标直接计算从而优化空间复杂度。
  • 测试结果:

1260 一维展开.png

结束语

过去成就现在,当下决定未来。人生的答案不是想出来的,是一步步走出来的。我们能不能成为更好的自己,过上更好的生活,正依赖于我们现在所做的选择和脚下正在走的路。要相信,我们都有创造美好未来的力量。新的一天,加油!