跳跃游戏 II-leetcode45-贪心-java题解

48 篇文章 0 订阅
5 篇文章 0 订阅

问题说明来源leetcode

一、问题描述

45. 跳跃游戏 II

难度中等1918

给定一个长度为 n0 索引整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]

示例 1:

输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
     从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例 2:

输入: nums = [2,3,0,1,4]
输出: 2

提示:

  • 1 <= nums.length <= 104
  • 0 <= nums[i] <= 1000

二、题解:

思考过程:

如果扫描一定范围,取其中的最大值来作为条约点可以不?

对于第一个点肯定是索引为0的,这个元素肯定是要计入的。

那么当拿到nums[0]了呢?

先对【0,nums[0]】范围的元素继续扫描,取最大的。

但是最大的好像不一定行,因为如果该最大值距离上一个踩点很近,

比如说

元素:5 4 3 2 1 2 3 3
索引:0 1 2 3 4 5 6 7

上面的结果对于第一次扫描到的4肯定不是结果

那么好像不是取最大的,而是???

对于范围【0,5】的元素,应该是考虑len - 1 - nums[i]的大小才对!

但是这样子真能找到最小跳跃步数吗?会不会还增加了一些步数?

1 . . . . . . 1 . . . . . ? . . 1 . . . . . . . 1

好像模拟不出来有什么情况,好像真的没问题。

那就这样

class Solution {
       public int jump(int[] nums) {
        if (nums.length == 1) return 0;
        int count = 0;
        int index = 0;
        for (int i = 1; i < nums.length; i++) {
            if (nums[index] < nums.length - index - 1){
                count++;
                // 寻找下一个power,power 是使得len - nums[j] - j - 1最小的;
                int tmp = i;
                for (int j = i;j <= nums[index] + index; j++) {
                    if ( nums.length - nums[j] - j <= nums.length - nums[tmp] - tmp) tmp = j;
                }
                i = nums[index] + index;
                index = tmp;
            }else {
                break;
            }

        }
        return count+1;
    }
}

ok了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是电话号码的字母组合问题的 C++ 代码实现: ``` class Solution { public: vector<string> letterCombinations(string digits) { unordered_map<char, string> mapping = { {'2', "abc"}, {'3', "def"}, {'4', "ghi"}, {'5', "jkl"}, {'6', "mno"}, {'7', "pqrs"}, {'8', "tuv"}, {'9', "wxyz"} }; vector<string> res; if (digits.empty()) { return res; } string combination; backtrack(res, combination, digits, 0, mapping); return res; } void backtrack(vector<string>& res, string& combination, string& digits, int index, unordered_map<char, string>& mapping) { if (index == digits.size()) { res.push_back(combination); return; } for (char c : mapping[digits[index]]) { combination.push_back(c); backtrack(res, combination, digits, index + 1, mapping); combination.pop_back(); } } }; ``` 其中 `letterCombinations` 函数用来生成所有的字母组合,`backtrack` 函数用来进行回溯操作。在 `letterCombinations` 函数中,首先根据数字字符和字母的映射关系创建了一个 `unordered_map` 对象 `mapping`。然后定义了一个空字符串 `combination` 和一个空 vector `res` 来保存最终结果。最后调用了 `backtrack` 函数来生成所有的字母组合。在 `backtrack` 函数中,首先判断是否达到了数字字符串的末尾,如果是,则将当前的 `combination` 字符串保存到 `res` 中。否则,遍历当前数字字符所能表示的所有字母,依次加入到 `combination` 字符串中,然后递归调用 `backtrack` 函数,添加下一个数字字符所能表示的字母。递归完成后,需要将 `combination` 字符串还原到上一个状态,以便进行下一次回溯。最终返回 `res` 数组即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值