zoukankan      html  css  js  c++  java
  • 剑指66.机器人的运动范围

    题目描述

    地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
     

    思路

    与《矩阵中的路径》类似,但这道题不需要回溯,因为如果满足条件一定可以走到。而《矩阵中的路径》如果路径走不通,需要回溯。

    思路1:通过递归的去查找某一个下标位置的两个方向即可(要么往右要么往下),在到达某一个位置的时候,判断是否越界,是否被访问过,是否满足数位之和小于k        (最优解)

    思路2:逐个遍历每一个方格,判断数位之和是否小于等于k,并且判断当前位置能否由 上边的位置 和 左边的位置 走来即可。   (如果k=0时,仍需要不断判断,该方法效率较低)

    ☆☆解法1

    public class Solution {
        private int sum = 0;
        public int movingCount(int threshold, int rows, int cols) {
            boolean[][] vis = new boolean[rows][cols];
            solve(0,0,rows,cols,threshold,vis);
            return sum;
        }
        // 牢记如何求位数和!!
        private int cal(int num){
            int res = 0;
            while (num > 0){
                res += num % 10;
                num /= 10;
            }
            return res;
        }
        private void solve(int x, int y, int rows, int cols, int k, boolean[][] vis) {
            if (x < 0 || y < 0 || x >= rows || y >= cols || vis[x][y] || (cal(x) + cal(y) > k)){
                return;
            }
            // 当前位置(x,y)是可以走的,那么就从当前位置往右下移动即可。
            vis[x][y] = true;
            sum++;
            solve(x,y+1,rows,cols,k,vis); //
            solve(x+1,y,rows,cols,k,vis); //// 既然不用回溯,就不需要递归x-1和y-1的坐标了,因为从左上角出发,每次只需要往右和往下搜索
    //        solve(x-1,y,rows,cols,k,vis);
    //        solve(x,y-1,rows,cols,k,vis);
        }
    }

    ☆解法2

    public class Solution {
        public int movingCount(int threshold, int rows, int cols) {
            int sum = threshold >= 0 ? 1 : 0;
            boolean[][] vis = new boolean[rows][cols];
            vis[0][0] = true;
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    if ((cal(i) + cal(j)) <= threshold){
                        // 判断能否从上边走过来
                        if (i-1 >= 0 && vis[i-1][j]){
                            sum++;
                            vis[i][j] = true;
                            // 判断能否从左边走过来
                        }else if (j-1 >= 0 && vis[i][j-1]){
                            sum++;
                            vis[i][j] = true;
                        }
                    }
                }
            }
            return sum;
        }
        private int cal(int num){
            int res = 0;
            while (num > 0){
                res += num % 10;
                num /= 10;
            }
            return res;
        }
    }
     
  • 相关阅读:
    centos出现“FirewallD is not running”怎么办
    Centos7开放及查看端口
    phpRedis函数使用总结
    如何在Windows的PHPstudy中使用redis
    Redis命令操作详解
    不可不知 DDoS的攻击原理与防御方法
    DDoS 攻击与防御:从原理到实践
    ORM Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous
    PHP常用函数大全500+
    Linux彻底卸载Nginx
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/13673072.html
Copyright © 2011-2022 走看看