从零学算法

这篇具有很好参考价值的文章主要介绍了从零学算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1575.给你一个 互不相同 的整数数组,其中 locations[i] 表示第 i 个城市的位置。同时给你 start,finish 和 fuel 分别表示出发城市、目的地城市和你初始拥有的汽油总量
每一步中,如果你在城市 i ,你可以选择任意一个城市 j ,满足 j != i 且 0 <= j < locations.length ,并移动到城市 j 。从城市 i 移动到 j 消耗的汽油量为 |locations[i] - locations[j]|,|x| 表示 x 的绝对值。
请注意, fuel 任何时刻都 不能 为负,且你 可以 经过任意城市超过一次(包括 start 和 finish )。
请你返回从 start 到 finish 所有可能路径的数目。
由于答案可能很大, 请将它对 10^9 + 7 取余后返回。
示例 1:
输入:locations = [2,3,6,8,4], start = 1, finish = 3, fuel = 5
输出:4
解释:以下为所有可能路径,每一条都用了 5 单位的汽油:
1 -> 3
1 -> 2 -> 3
1 -> 4 -> 3
1 -> 4 -> 2 -> 3
示例 2:
输入:locations = [4,3,1], start = 1, finish = 0, fuel = 6
输出:5
解释:以下为所有可能的路径:
1 -> 0,使用汽油量为 fuel = 1
1 -> 2 -> 0,使用汽油量为 fuel = 5
1 -> 2 -> 1 -> 0,使用汽油量为 fuel = 5
1 -> 0 -> 1 -> 0,使用汽油量为 fuel = 3
1 -> 0 -> 1 -> 0 -> 1 -> 0,使用汽油量为 fuel = 5文章来源地址https://www.toymoban.com/news/detail-455958.html

  • 直接上题号吧,不是我能解的:1575
  • 他人题解:通常情况下,会给定一个形状的地图,然后给定起点(不给你就枚举每个起点就好)终点,然后根据具体规则(比如只能往上和往右)走,有起点和规则你就算出最优解即可。但是这题没有告诉你怎么走,甚至到达终点以后,油量足够的话还能继续走。那么这时就需要记忆化搜索了,设置缓存器 cache[i][fuel] ,代表从位置 i 出发,当前剩余的油量为 fuel 的前提下,到达目标位置的「路径数量」(个人理解,这就是可以得到所有不重复且不遗漏的所有情况的一种设置,我只想到 cache[i] 代表从 i 出发到终点有多少路径,然而这样就忽略了油量这个条件)。然后 dfs 的基本结构我就引用一下
  1. 设计好递归函数的「入参」和「出参」
  2. 设置好递归函数的出口(Base Case)
  3. 编写「最小单元」处理逻辑
  • 第一点好说,题目给的几个输入:所有城市,起点,终点以及油量(先用着,不够再加),Base Case 在本题具体体现为怎么样算一条有效路径,怎么样就无效了,最小单元处理逻辑的话直接循环累加当前点到其他点后到终点的路径数(看代码好理解一点)。首先无效情况,当前点如果到不了终点,那肯定不可能先去其他点再到终点(三角形两边之和大于第三边,也就是说最少也需要起点直达终点的油量),然后循环累加,记得当前位置如果在终点说明已经有一条有效路径。
  •   int mod = 1000000007;
      // 缓存器:用于记录「特定状态」下的结果
      // cache[i][fuel] 代表从位置 i 出发,当前剩余的油量为 fuel 的前提下,到达目标位置的「路径数量」
      int[][] cache;
      public int countRoutes(int[] ls, int start, int end, int fuel) {
          int n = ls.length;
          // 初始化缓存器
          // 之所以要初始化为 -1
          // 是为了区分「某个状态下路径数量为 0」和「某个状态尚未没计算过」两种情况
          cache = new int[n][fuel + 1];
          for (int i = 0; i < n; i++) {
              Arrays.fill(cache[i], -1);
          }
          
          return dfs(ls, start, end, fuel);
      }
      /**
       * 计算「路径数量」
       * @param ls 入参 locations
       * @param u 当前所在位置(ls 的下标)
       * @param end 目标哦位置(ls 的下标)
       * @param fuel 剩余油量
       * @return 在位置 u 出发,油量为 fuel 的前提下,到达 end 的「路径数量」
       */
      int dfs(int[] ls, int cur, int end, int fuel){
          int need = Math.abs(ls[cur]-ls[end]);
          if(need > fuel){
              cache[cur][fuel] = 0;
              return 0;
          }
          int n = ls.length;
          // 计算油量为 fuel,从位置 u 到 end 的路径数量
          // 由于每个点都可以经过多次,如果 u = end,那么本身就算一条路径
          int sum = cur == end? 1 : 0;
          // 从这个结点开枝散叶了,每次都看看去了其他任何能到达的点以后还能不能得到有效路径
          for(int i=0;i<n;i++){
              if(i == cur) continue;
              need = Math.abs(ls[i]-ls[cur]);
              if(need <= fuel){
              	// 
                  sum += dfs(ls,i,end,fuel-need);
                  sum %= mod;
              }
          }
          cache[cur][fuel] = sum;
          return sum;
      }
    
    

到了这里,关于从零学算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 从零学算法560

    560 . 和为 K 的子数组 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 。 示例 1: 输入:nums = [1,1,1], k = 2 输出:2 示例 2: 输入:nums = [1,2,3], k = 3 输出:2 比较容易想到的是暴力解法(我承认我想不到)。为了不遗漏的得到每个连续

    2024年02月15日
    浏览(34)
  • 从零学算法79

    79 .给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使

    2024年02月11日
    浏览(35)
  • 从零学算法55

    55 .给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 示例 1: 输入:nums = [2,3,1,1,4] 输出:true 解释:可以先跳 1 步,从下标

    2024年02月21日
    浏览(63)
  • 从零学算法50

    50 .实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即,xn )。 示例 1: 输入:x = 2.00000, n = 10 输出:1024.00000 示例 2: 输入:x = 2.10000, n = 3 输出:9.26100 示例 3: 输入:x = 2.00000, n = -2 输出:0.25000 解释:2-2 = 1/22 = 1/4 = 0.25 还真没我想的那么简单,这题可以学一下快速幂,我就直

    2024年02月07日
    浏览(35)
  • 从零学算法154

    154 .已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,4,4,5,6,7] 在变化后可能得到: 若旋转 4 次,则可以得到 [4,5,6,7,0,1,4] 若旋转 7 次,则可以得到 [0,1,4,4,5,6,7] 注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为

    2024年02月13日
    浏览(36)
  • 从零学算法113

    113 .给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1: 输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 输出:[[5,4,11,2],[5,8,4,5]] 示例 2: 输入:root = [1,2,3]

    2024年02月11日
    浏览(36)
  • 从零学算法2848

    2848 .给你一个下标从 0 开始的二维整数数组 nums 表示汽车停放在数轴上的坐标。对于任意下标 i,nums[i] = [starti, endi] ,其中 starti 是第 i 辆车的起点,endi 是第 i 辆车的终点。 返回数轴上被车 任意部分 覆盖的整数点的数目。 示例 1: 输入:nums = [[3,6],[1,5],[4,7]] 输出:7 解释:

    2024年02月09日
    浏览(28)
  • 从零学算法(LCR 180)

    文件组合 .待传输文件被切分成多个部分,按照原排列顺序,每部分文件编号均为一个 正整数(至少含有两个文件)。传输要求为:连续文件编号总和为接收方指定数字 target 的所有文件。请返回所有符合该要求的文件传输组合列表。 注意,返回时需遵循以下规则: 每种组合

    2024年02月07日
    浏览(34)
  • 从零学算法(剑指 Offer 45)

    输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。 示例 1: 输入: [10,2] 输出: “102” 示例 2: 输入: [3,30,34,5,9] 输出: “3033459” 我的原始人解法:直接冒泡排序,把最先应该拼接的那个数不断后移,然后拼接即可。关键就

    2024年02月10日
    浏览(39)
  • 从零学算法 (剑指 Offer 13)

    地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+

    2024年02月11日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包