leetcode 55. 跳跃游戏

256 阅读1分钟

题目链接

解法一 贪心

思路:针对每个索引计算从该索引可达的最远索引。

func canJump(nums []int) bool {
    l := len(nums)
    if l == 0 {
        panic("nums is empty")
    }
    if l == 1 {
        return true
    }
    if nums[0] == 0 {
        return false
    }
    e := l-1
    if nums[0] >= e {
        return true
    }
    dp := make([]int, l)
    dp[0] = nums[0]
    for i := 1 ; i < l; i++ {
        // 先保证可达
        if i > dp[i-1] {
            // 不可达,算法结束
            return false
        }
        // 计算从i可达的j
        j := i+nums[i]
        // 尝试更新最远可达索引
        if j > dp[i-1] {
            dp[i] = j
            if j >= e {
                // 可达最后一个索引,直接返回
                return true
            }
        } else {
            dp[i] = dp[i-1]
        }
    }
    // 执行到此处说明肯定可以到达最后一个索引
    return true
}

时间复杂度O(n)O(n),空间复杂度O(n)O(n)

解法二 在解法一的基础上优化空间复杂度

func canJump(nums []int) bool {
    l := len(nums)
    if l == 0 {
        panic("nums is empty")
    }
    if l == 1 {
        return true
    }
    // l > 1
    if nums[0] == 0 {
        return false
    }
    e := l-1
    // 当前最远可达索引
    maxJ := nums[0]
    if maxJ >= e {
        // 可以到达最后一个索引,直接返回
        return true
    }
    for i := 1 ; i < l; i++ {
        // 先保证当前位置可达
        if i > maxJ {
            // 到不了该位置,直接返回
            return false
        }
        // 计算从i可达的j
        j := i+nums[i]
        // 尝试更新maxJ
        if j > maxJ {
            maxJ = j
            if j >= e {
                // 可以到达最后一个索引,直接返回
                return true
            }
        }
    }
    // 执行到这里,说明最后一个位置可达
    return true
}

时间复杂度O(n)O(n),空间复杂度O(1)O(1)