通过率 37% · 提交 1,829 · 通过 681
小慕正在设计一个跳格子游戏的关卡,格子的总数为count。每回合,小慕可以从给定的步数数组steps中选择一个步数,连续向前跳对应的格子数。三个回合内,小慕需要恰好跳到最后一格。 如果存在这样的步数组合,请输出其中数组索引之和最小的组合。题目保证这样的组合是唯一的。 注意:数组中的步数可以重复出现,但每个元素只能使用一次。
这类题属于华为 OD 机考真题方向中「100分 / 双指针」方向的高频题型,通常考察对「100分 / 双指针」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
第一行输入为房子总格数count,它是整数类型int。
第二行输入为每回合可能连续跳过的步数,它是整数数组类型。
count <= 10000;
3 <= steps.length <= 10000;
-100000 <= steps[i] <= 100000;
返回索引和最小满足要求的步数组合。
注意:顺序保持steps中的原有顺序。
示例 1
输入示例
1,5,2,0,2,4 9
输出示例
5,2,2
示例 2
输入示例
1,4,5,2,0,2 9
输出示例
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
相关图解步骤
先看指定步骤补关键知识点,再回到本题完成标准输入输出。
注意,本题和 经典题型、三数之和 基本完全一致。区别仅仅在于本题需要找到 下标和最小 的索引。
首先要理解题意。输出描述的断句是这样的:返回 索引和最小(且)满足要求的步数组合。索引和 一词是一个整体,表示需要找到三个数的索引的总和。
在 经典题型、三数之和 中我们知道,要使用 双指针算法,我们必须对原数组进行 从小到大的排序。但是在本题中,一旦对原数组进行排序,那么其原来的索引就丢失了。
因此,我们在排序的过程中,除了对已知数据 num 进行排序,还必须同时储存每一个元素在原输入数组 lst 中的索引 idx。故排序过程如下:
注意此处我们新建的 nums 是一个 二维数组,其中的内层元素 (num, idx) 是一个 二元组,其中 num 是元素值,idx 是 num 在原输入数组 lst 中的索引。nums 中元素的排序,会 先按照 `num` 的大小进行从小到大排序,当 num 相等时,则 按照其出现在 `lst` 中的索引 `idx` 进行从小到大排序。
譬如对于例子:
我们会得到:
接下来是非常经典的 双指针过程。
对于 nums 中的元素,我们遍历里面里面的每一组 (num, idx)(其在 nums 中的索引值为 i),将其固定为选择的 第一个元素。而剩余的 第二个元素 和 第三个元素,分别设置 left 和 right 从 i+1 和 n-1 的位置从两边往中间靠拢。
代码框架如下:
接下来就是填充双指针过程,即上述代码框架中的 while 循环。
我们令当前的三数之和为 sum3 = first + nums[left][0] + nums[right][0]。当:
sum3 > target 时,三数之和太大,sum3 需要减小,right 左移sum3 < target 时,三数之和太小,sum3 需要增加,left 右移sum3 == target 时,此时所选择的三个数的和为题目输入的目标和 target,我们需要更新答案。同时 只有 `right` 左移。sum3 == target 时只移动 right?此处需要特别讨论,为什么在 sum3 == target 的时候,我们的代码中 只有 `right` 左移,而不是 left 右移或者 left 和 right 同时移动。
在 经典题型、三数之和 中,由于我们要找的是 元素组合,而不是元素的索引组合,因此我们无论写成 left 右移、right 左移还是 left 和 right 同时移动,答案都是正确的。
这三种写法,都能够避免 while 的死循环(也是这里指针移动的唯一作用)。这是因为,只需要保证 while 中的每一个 if 分支中,至少有一个指针是在变化的,那么 while 中的 left < right 条件就一定会有不成立的时候,会顺利退出循环。
但是在本题中,由于我们要找的是 元素的索引组合,并且要求是找到 索引和最小 的索引组合。可能会存在一种情况,即 nums[right-1][0] == nums[right][0]。由于当 num 相等时元素按照在原数组中的索引 idx 进行从小到大排序,此时必然存在 nums[right-1][1] < nums[right][1]。
譬如数组:
假设 target = 9,当 i = 1,left = 2,right = 5 时,我们已经找到了 (2, 0), (2, 2), (5, 3) 这三个元素它们的数字和为 target,索引和为 5。
由于 nums[4][0] == nums[5][0] == 5。如果此时我们移动了 left,我们将会错过索引和更小的 (2, 0), (2, 2), (5, 1) 这样的组合(i = 1,left = 2,right = 4,索引和为 3)。所以 当我们找到一组答案的时候,不能够移动 `left`(即使这样在其他题目中的正确的),只能移动 `right`。这样才能够尽可能地找到更小的索引和。
因此,整体的代码如下:
复杂度分析 设数组长度为 n。
总时间复杂度为 O(n²),空间复杂度为 O(n),主要是带原始下标的排序副本 nums。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
4,5,0
示例 3
输入示例
-1,2,4,9 12
输出示例
-1,4,9
时间限制 1000 ms · 内存限制 128 MB
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有