5331跳跃游戏V

题目:给你一个整数数组 arr 和一个整数 d 。每一步你可以从下标 i 跳到:
    i + x ,其中 i + x < arr.length 且 0 < x <= d 。
    i - x ,其中 i - x >= 0 且 0 < x <= d 。
除此以外,你从下标 i 跳到下标 j 需要满足:arr[i] > arr[j] 且 arr[i] > arr[k] ,其中下标 k 是所有 i 到 j 之间的数字(更正式的,min(i, j) < k < max(i, j))。你可以选择数组的任意下标开始跳跃。请你返回你 最多 可以访问多少个下标。请注意,任何时刻你都不能跳到数组的外面。

来源:https://leetcode-cn.com/problems/jump-game-v/

法一:自己的代码

思路:用备忘录进行记录,利用递归进行遍历,注意写递归的时候到一定要注意递归什么时候结束,即递归的结束条件,本题的递归结束条件是走到一个位置它的左右两边都大于等于它,这时便无法继续跳跃,结束递归,返回1.

from typing import List
class Solution:
    def maxJumps(self, arr: List[int], d: int) -> int:
        memo = {}
        size = len(arr)
        def jishu(index):
            print(memo)
            if index in memo.keys():
                return memo[index]
            # a,b分别是朝左朝右可以跳到的最远位置
            a = max(0, index-d)
            b = min(size, index+d+1)
            p,q = 0,0
            # 朝左跳的时候,索引由大到小,所以逆序
            for i in range(a,index)[::-1]:
                if arr[i] >= arr[index]:
                    break
                # 进行递归
                p = max(jishu(i)+1,p)
            # 朝右跳
            for j in range(index+1,b):
                if arr[j] >= arr[index]:
                    break
                q = max(jishu(j)+1,q)
            # 这里必须要加1,因为当跳到最低点的时候,无法朝左和朝右跳,p q都是0,这是跳的步数是1
            memo[index] = max(p,q,1)
            return memo[index]
        for i in range(size):
            jishu(i)
        print(memo)
        return max(memo.values())
View Code

改进后的:利用装饰器进行记录数据,同时for循环的时候就求出最大值会节省时间.

from typing import List
from functools import lru_cache
class Solution:
    def maxJumps(self, arr: List[int], d: int) -> int:
        memo = {}
        size = len(arr)
        @lru_cache(None)
        def jishu(index):
            # a,b分别是朝左朝右可以跳到的最远位置
            a = max(0, index-d)
            b = min(size, index+d+1)
            ans = 0
            # 朝左跳的时候,索引由大到小,所以逆序
            for i in range(a,index)[::-1]:
                if arr[i] >= arr[index]:
                    break
                # 进行递归,注意这里加的这个1是index的这个位置
                ans = max(jishu(i)+1,ans)
            # 朝右跳
            for j in range(index+1,b):
                if arr[j] >= arr[index]:
                    break
                ans = max(jishu(j)+1,ans)
            # 用装饰器的话,不需要用备忘录来记录,直接返回即可
            # 当走到最低点时,这时就会取1
            return max(ans,1)
        res = 0
        for i in range(size):
            res = max(jishu(i), res)
        return res
if __name__ == '__main__':
    duixiang = Solution()
    # a = duixiang.maxJumps(arr=[3,3,3], d=1)
    a = duixiang.maxJumps(arr=[22,29,52,97,29,75,78,2,92,70,90,12,43,17,97,18,58,100,41,32], d=17)
    # a = duixiang.maxJumps(arr=[22,29,52], d=17)
    # a = duixiang.maxJumps(arr=[1,2,3], d=17)
    # a = duixiang.maxJumps(arr=[6,4,14,6,8,13,9,7,10,6,12], d=2)
    print(a)
View Code

ttt

原文地址:https://www.cnblogs.com/xxswkl/p/12252846.html