跳跃游戏(二):DFS 求解最少跳跃次数与最优路径

题目描述

给定一个非负整数数组 nums,数组中每个元素代表在该位置可以跳跃的最大长度。要求找出从数组起始位置(下标 0)跳到最后一个位置(下标 nums.size() - 1)的最少跳跃次数 ,并输出对应的最优跳跃过程 (如示例中的 0->1->4 表示从下标 0 跳到 1,再从 1 跳到 4)。

解题思路

采用深度优先搜索(DFS)的思路,从起始位置开始,尝试所有可能的跳跃步数,递归探索每一条可能的路径,同时记录跳跃次数和路径。当到达或超过最后一个位置时,更新最少跳跃次数和对应的最优路径。

核心逻辑

  1. 递归探索 :从当前位置 i 出发,尝试跳跃 1nums[i] 步,递归进入下一个位置 next
  2. 路径与次数更新:每进入一个位置,将其加入当前路径;当到达终点时,若当前跳跃次数更少,则更新最少次数和最优路径。
  3. 回溯:探索完当前位置的所有可能跳跃后,将当前位置从路径中移除,回溯以探索其他可能路径。

代码实现

cpp 复制代码
#include <iostream>
#include <vector>
#include <climits>
using namespace std;

// 存储最优跳跃路径
vector<int> best_path;
// 最少跳跃次数,初始化为整型最大值
int min_jumps = INT_MAX;
// 存储跳跃数组
vector<int> nums;

// 深度优先搜索函数
// i:当前位置;cnt:已跳跃次数;path:当前路径
void dfs(int i, int cnt, vector<int>& path) {
    // 将当前位置加入路径
    path.push_back(i);
    
    // 终止条件:到达或超过最后一个位置
    if (i >= nums.size() - 1) {
        // 若当前跳跃次数更少,更新最少次数和最优路径
        if (cnt < min_jumps) {
            min_jumps = cnt;
            best_path = path;
        }
        // 回溯,移除当前位置
        path.pop_back();
        return;
    }
    
    // 尝试从当前位置跳出的所有可能步数
    for (int j = 1; j <= nums[i]; j++) {
        int next = i + j;
        // 防止越界,直接跳到终点
        if (next >= nums.size()) {
            next = nums.size() - 1;
        }
        dfs(next, cnt + 1, path);  // 递归探索下一个位置
    }
    
    // 回溯,移除当前位置(所有子路径探索完后)
    path.pop_back();
}

int main() {
    int n;
    cin >> n;
    nums.resize(n);
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
    }
    
    vector<int> current_path;  // 记录当前递归路径
    dfs(0, 0, current_path);
    
    // 输出最少跳跃次数和最优路径
    cout << min_jumps << " ";
    for (int i = 0; i < best_path.size(); i++) {
        if (i > 0) {
            cout << "->";  // 路径中位置间用->连接
        }
        cout << best_path[i];
    }
    cout << endl;
    
    return 0;
}

代码解释

  • 全局变量best_path 存储最优路径,min_jumps 记录最少跳跃次数,nums 存储输入的跳跃数组。
  • dfs 函数
    • 每次进入函数先将当前位置 i 加入路径 path
    • 若到达终点,判断是否更新最少次数和最优路径,然后回溯。
    • 遍历当前位置可跳跃的步数,递归探索下一个位置,探索完所有子路径后回溯。
  • main 函数
    • 读取输入的数组长度和数组元素。
    • 调用 dfs 函数从起始位置 0 开始探索。
    • 最后输出最少跳跃次数和最优路径。

示例运行

输入

复制代码
5
2 3 1 1 4

输出

复制代码
2 0->1->4

解释 :最少需要跳跃 2 次,路径为从 0 跳到 1,再从 1 跳到 4

复杂度分析

  • 时间复杂度:最坏情况下,需要探索所有可能的跳跃路径,时间复杂度为 O(2n),其中 n 是数组长度。因为每个位置都可能有多种跳跃选择,呈现指数级增长。
  • 空间复杂度:主要用于存储递归栈和路径,空间复杂度为 O(n),其中 n 是数组长度,递归深度最多为 n,路径存储也最多为 n 个元素。

优化思路

若要处理更大规模的数组,可添加剪枝逻辑:当当前跳跃次数已经大于等于已知的最少跳跃次数时,直接终止当前路径的探索,避免无效递归,可有效减少时间消耗。

相关推荐
j_xxx404_7 小时前
数据结构:单链表的应用(力扣算法题)第二章
c语言·数据结构·算法·leetcode
艾醒8 小时前
大模型面试题剖析:大模型多机多卡微调全解析
人工智能·深度学习·算法
studytosky9 小时前
C语言数据结构之双向链表
c语言·数据结构·c++·算法·链表·c
max5006009 小时前
期货交易策略自动化实现
运维·开发语言·人工智能·算法·自动化·线性回归
白熊1889 小时前
【论文精读】基于YOLOv3算法的高速公路火灾检测
算法·yolo·yolov3
l1t10 小时前
利用DeepSeek编写验证xlsx格式文件中是否启用sharedStrings.xml对读写效率影响python程序
xml·开发语言·python·算法·xlsx
500佰10 小时前
Nano Banana 复刻分镜,多图结合片刻生成想要的视频
人工智能·算法
小O的算法实验室10 小时前
2023年IEEE IOTJ SCI1区TOP,动态环境下无人机目标覆盖任务路径规划,深度解析+性能实测
算法·无人机·论文复现·智能算法·智能算法改进
evolution_language10 小时前
LintCode第401题-排序矩阵中的从小到大第k个数
java·算法·矩阵·排序算法·堆排序·练码精选100题