ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

15-lt-机器人的运动范围

2021-11-13 18:30:44  阅读:151  来源: 互联网

标签:单元格 15 int 机器人 si sj lt 可达解 visited


一、题目

剑指 Offer 13. 机器人的运动范围

二、解法思路

 2.1 看到题目想到的思路

看到题目首选想到的是 机器人只能 往右和下方向移动,并且不能超出临界和数位之和;依次编码,发现在大的矩阵中,发现有些数位之和的位置能满足 但是走不通,因此找到了 base case 联通性,也就是机器人能否到达下一个条件满足区域。

参考:解题思路

下面看下别人的图:图片来源 图片地址

 三角形区域都是满足条件的位置,但是我们从(0,0)处出发,会发现我们不能够走到下一个连通区域。

 

 能够发现在(9,0)和(0,9)的位置,我们能够将一些不可达的解转变为可达解;因此对于(9,0)和(0,9)的位置我们需要单独处理;

(9,10)和(10,9)也能够将不可达解转换为可达解,也需要进行注意;

 

根据可达解的结构和连通性,易推出机器人可 仅通过向右和向下移动,访问所有可达解 。

三角形内部: 全部连通,易证;
两三角形连通处: 若某三角形内的解为可达解,则必与其左边或上边的三角形连通(即相交),即机器人必可从左边或上边走进此三角形。

 

实际上这边还有一个知识点会经常使用到:数位之和

int sums(int x){
    int s = 0;
    while(x != 0) {
        s += x % 10;
        x = x / 10;
    }
    return s;
}


2.2 思路和题解是否有一致 ,是否有更好的解法

不一致,选择使用BFS或者DFS进行求解

解题方法

BFS: 使用队列进行遍历

广度优先遍历 BFS
BFS/DFS : 两者目标都是遍历整个矩阵,不同点在于搜索顺序不同。DFS 是朝一个方向走到底,再回退,以此类推;BFS 则是按照“平推”的方式向前搜索。
BFS 实现: 通常利用队列实现广度优先遍历。
算法解析:
初始化: 将机器人初始点 (0, 0)(0,0) 加入队列 queue ;
迭代终止条件: queue 为空。代表已遍历完所有可达解。
迭代工作:
单元格出队: 将队首单元格的 索引、数位和 弹出,作为当前搜索单元格。
判断是否跳过: 若 ① 行列索引越界 或 ② 数位和超出目标值 k 或 ③ 当前元素已访问过 时,执行 continue 。
标记当前单元格 :将单元格索引 (i, j) 存入 Set visited 中,代表此单元格 已被访问过 。
单元格入队: 将当前元素的 下方、右方 单元格的 索引、数位和 加入 queue 。
返回值: Set visited 的长度 len(visited) ,即可达解的位置。

class Solution {
    public int movingCount(int m, int n, int k) {
        boolean[][] visited = new boolean[m][n];
        int res = 0;
        //创建队列
        Queue<int[]> queue = new LinkedList<int[]>();

        queue.add(new int[]{0, 0, 0, 0});

        while (queue.size() > 0) {
            //第一个节点
            int[] x = queue.poll();
            int i = x[0], j = x[1], si = x[2], sj = x[3];
            if (i >= m || j >= n || k < si + sj || visited[i][j]) continue;
            visited[i][j] = true;
            res++;
            queue.add(new int[]{i + 1, j, (i + 1) % 10 != 0 ? si + 1 : si - 8, sj});
            queue.add(new int[]{i, j + 1, si, (j + 1 % 10 != 0 ? sj + 1 : sj - 8)});
        }
        return  res;
    }
}

DFS:递归调用至条件

深度优先搜索: 可以理解为暴力法模拟机器人在矩阵中的所有路径。DFS 通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。
剪枝:在搜索中,遇到数位和超出目标值、此元素已访问,则应立即返回,称之为 可行性剪枝 。
算法解析:
递归参数: 当前元素在矩阵中的行列索引 i 和 j ,两者的数位和 si, sj 。
终止条件: 当 ① 行列索引越界 或 ② 数位和超出目标值 k 或 ③ 当前元素已访问过 时,返回 00 ,代表不计入可达解。
递推工作:
标记当前单元格 :将索引 (i, j) 存入 Set visited 中,代表此单元格已被访问过。
搜索下一单元格: 计算当前元素的 下、右 两个方向元素的数位和,并开启下层递归 。
回溯返回值: 返回 1 + 右方搜索的可达解总数 + 下方搜索的可达解总数,代表从本单元格递归搜索的可达解总数。

class Solution {
    int m, n, k;
    boolean[][] visited;
    public int movingCount(int m, int n, int k) {
        this.m = m; this.n = n; this.k = k;
        this.visited = new boolean[m][n];
        return dfs(0, 0, 0, 0);
    }
    public int dfs(int i, int j, int si, int sj) {
        if(i >= m || j >= n || k < si + sj || visited[i][j]) return 0;
        visited[i][j] = true;
        return 1 + dfs(i + 1, j, (i + 1) % 10 != 0 ? si + 1 : si - 8, sj) + dfs(i, j + 1, si, (j + 1) % 10 != 0 ? sj + 1 : sj - 8);
    }
}

标签:单元格,15,int,机器人,si,sj,lt,可达解,visited
来源: https://blog.csdn.net/qq_35746739/article/details/121284277

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有