LeetCode.1260. 二维网格迁移____原地暴力 / 降维+循环数组直接定位

1260. 二维网格迁移

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

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

  1. 位于 grid[i][j] 的元素将会移动到 grid[i][j + 1]。
  2. 位于 grid[i][n - 1] 的元素将会移动到 grid[i + 1][0]。
  3. 位于 grid[m - 1][n - 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]]

提示:

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

Solution1(原地暴力):

  • 我们可以直接原地暴力模拟迁移即可;

Code1:

/* 原地暴力 */
class Solution {
    public List<List<Integer>> shiftGrid(int[][] grid, int k) {
        int m = grid.length;
        int n = grid[0].length;
        List<List<Integer>> res = new ArrayList<>();
        if(k == 0){
            for(int i=0;i<m;i++){
                List<Integer> list = new ArrayList<>();
                for(int j=0;j<n;j++){
                    list.add(grid[i][j]);
                }
                res.add(list);
            }
            return res;
        }
        int count = 0;
        while(count != k){
            int temp = grid[m - 1][n - 1];
            for(int i=0;i<m;i++){
                List<Integer> list = null;
                if(count == k - 1)
                    list = new ArrayList<>();
                for(int j=0;j<n;j++){
                    int t_temp = temp;
                    temp = grid[i][j];
                    grid[i][j] = t_temp;
                    if(count == k - 1)
                        list.add(t_temp);
                }
                if(count == k - 1)
                    res.add(list);
            }
            count++;
        }
        
        return res;
    }
}

Solution2(降维+循环数组直接定位):

  • 对于矩阵转移类似的题目,我们要先多多观察,我们发现这里其实很像一个一维循环数组移动元素的问题,即尾部再往后面走就跑到了头部,且能降维就降维,因此我们可以把此二维转一维
  • 接着我们发现,我们没必要枚举k次迁移操作,我们发现迁移k次其实对于一维循环数组来说就是每个元素向后面移动k次即可,因此我们可以直接根据数学关系定位每个元素的位置;

Code2:

/* 二维转一维 + 循环数组直接定位 */
class Solution {
    public List<List<Integer>> shiftGrid(int[][] grid, int k) {
        int m = grid.length;
        int n = grid[0].length;
        List<List<Integer>> res = new ArrayList<>();
        int len = m * n;
        int[] aux = new int[len];
        int index = 0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                aux[index++] = grid[i][j]; 
            }
        }

        int[] mock = new int[len];
        for(int i=0;i<len;i++){
            mock[(i + k) % len] = aux[i];
        }

        List<Integer> list = null;
        for(int i=0;i<len;i++){
            if(i % n == 0)
                list = new ArrayList<>();
            list.add(mock[i]);
            if((i + 1) % n == 0)
                res.add(list);
        }

        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向光.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值