LeetCode-55.跳跃游戏(55-I, 45-II)

一、LeetCode-55.跳跃游戏

1. 参考:https://www.jb51.net/article/217248.htm

2. 代码实现

复制代码
#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))

int min_val(int x, int y) { return x < y ? x : y; }
int max_val(int x, int y) { return x > y ? x : y; }

/*
 * Input: [2,3,1,1,4] //can
 * Input: [3,2,1,0,4] //can not
 * rm[i] = max(rm[i-1], jump[i-1]) - 1; 出现 rm[i]<0则不能,否则能
 */
/* 解法一: 动态规划, 递推式 */
int can_jump(int *jump, int sz)
{
    int i, can_jump = 1;
    int *rm = calloc(sizeof(int), sz);

    for (i = 1; i < sz; i++) {
        rm[i] = max_val(rm[i-1], jump[i-1]) - 1;
        if (rm[i] < 0) {
            can_jump = 0;
            break;
        }
    }
    free(rm);

    return can_jump;
}

/* 解法二: 贪心算法,一直找每个位置能跳跃到的最大位置,只要出现能跳跃到最后一个位置则退出 */
int can_jump_2(int *jump, int sz)
{
    int i, mj = 0, can_jump = 0;

    /* mj表示最大能跳跃到的位置 */
    for (i = 0; i < sz; i++) {
        /* 前一个位置能跳跃到的最大位置还到不了i,则退出 */
        if (i > mj) break;
        mj = max_val(mj, jump[i]+i);
        if (mj >= sz - 1) {
            can_jump = 1;
            break;
        }
    }

    return can_jump;
}

int main()
{
    int arr1[] = {2,3,1,1,4};
    int ret1 = can_jump(arr1, ARRAY_SIZE(arr1));
    int arr2[] = {3,2,1,0,4};
    int ret2 = can_jump(arr2, ARRAY_SIZE(arr2));
    printf("func1: ret1=%d, ret2=%d\n", ret1, ret2);

    ret1 = can_jump_2(arr1, ARRAY_SIZE(arr1));
    ret2 = can_jump_2(arr2, ARRAY_SIZE(arr2));
    printf("func2: ret1=%d, ret2=%d\n", ret1, ret2);

    return 0;
}
复制代码

 

二、LeetCode-45.跳跃游戏-2

1. 参考:

https://www.cnblogs.com/GarrettWale/p/17135879.html //C实现参考的是它
https://www.jb51.net/article/217244.htm

2. 实现

复制代码
#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))

int max_val(int x, int y) { return x > y ? x : y; }

int max_jump(int *arr, int sz)
{
    int i, jump = 0, max_step = 0, right = 0;

    for (i = 0; i < sz; i++) {
        if (max_step < i) return -1; //[1]
        max_step = max_val(max_step, i + arr[i]); //[2]
        if (i == right && i != sz-1) { //[3]
            right = max_step;
            jump++;
            if (right >= sz -1) break; //[4]
        }
    }

    return jump;
}

int main()
{
    int arr1[] = {2,3,1,1,4};
    int ret1 = max_jump(arr1, ARRAY_SIZE(arr1));
    printf("func1: ret1=%d\n", ret1);

    int arr2[] = {2,4,1,1,1,0,5};
    int ret2 = max_jump(arr2, ARRAY_SIZE(arr2));
    printf("func1: ret2=%d\n", ret2);
}
复制代码

注释:
[1]: 前一个位置计算出的最远还跳不到当前下标位置,说明跳不到终点,返回-1.
[2]: 当前遍历位置能跳跃到的最大下标
[3]: 达到上一步能跳跃到的最大下标了,说明还需要多跳一次,其次,若上一步已经是终点了,就不用再跳了.
[4]: 优化, 若当前已经可以调到最后一个元素位置了,就不用再遍历了。

 

posted on   Hello-World3  阅读(2)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2023-02-16 调度器30—调度相关结构体—p->flags
2023-02-16 调度器42—进程exit退出流程

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示