• 1306跳跃游戏III


    题目: 这里有一个非负整数数组arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。请你判断自己是否能够跳到对应元素值为 0 的 任意 下标处。注意,不管是什么情况下,你都无法跳到数组之外。

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

    法一: 自己的代码   注意返回False和返回None都是正确的!因为系统内部会计算他们的布尔变量,都是False.

    这个里面如果某个索引被遍历了一遍就无需再遍历了,(即便这个索引只朝右或只超左被遍历过,也无需再遍历了,因为比如某个索引只超右遍历了,但它的超左的那个索引已经被记录到队列中了,或者是树的某个分支还没有被遍历,等待遍历,所以一定不会出现漏掉的情况)

    思路: 利用常规的回溯模板,类似于数独题的解法,每次回溯时,先判断以前是否遍历过,再判断索引位置值是否为0,再确定下次要回溯的索引,注意用这个模板的难点在于返回值的问题,如果所有的回溯分支都跳不到0,则返回值有两种情况,一种是False,即第一次进去超左超右都跳出去了,这时返回False,另一种是回溯的时候,返回False,这时直接pass,这时如果其它的分支也是pass的话,最后的返回值是None,这一点要明确.

    from collections import defaultdict
    from typing import List
    class Solution:
        def canReach(self, arr: List[int], start: int) -> bool:
            l = len(arr)
            memo = defaultdict(int)
            def recursion(index, val):
                # 先判断之前是否判断过,如果判断过,直接返回False
                if memo[index] == 1:
                    return False
                elif arr[index] == 0:
                    return True
                memo[index] += 1
                all = []
                # 用于确定下次遍历的索引
                if index + val > l-1:
                    pass
                else:
                    all.append((index+val, arr[index+val]))
                if index - val < 0:
                    pass
                else:
                    all.append((index-val, arr[index-val]))
                if len(all) == 0:
                    return False
    
                for i,j in all:
                    # 如果返回值为False或None,则继续判断,直到遍历完所有可以遍历的索引
                    a = recursion(i,j)
                    if a is False or a is None:
                        pass
                    else:
                        return a
            return True if recursion(index=start, val=arr[start]) else False
            # ans = recursion(index=start, val=arr[start])
            # if  ans is None or  ans is False:
            #     return False
            # else:
            #     return True
    if __name__ == '__main__':
        duixiang = Solution()
        a = duixiang.canReach(arr = [3,0,2,1,2], start = 2)
        # a = duixiang.canReach(arr = [4, 2, 3, 0, 3, 1, 2], start = 0)
        # a = duixiang.canReach(arr = [31, 70, 40, 4, 27, 28, 44, 17, 8, 16, 64, 14, 30, 17, 25, 61, 33, 50, 45, 67, 12, 43, 72, 0, 26, 24, 33, 66, 22,
        #  11, 61, 15, 2, 18, 51, 37, 34, 7, 14, 29, 37, 3, 40, 3, 61, 20, 24, 22, 53, 18, 58, 56, 16, 44, 14, 5, 6, 19, 72,
        #  46, 49, 10, 42, 40, 46, 10, 6, 34, 17, 68, 62, 34, 33, 68], start = 10)
        print(a)
    View Code

    法二: dfs

    思路: 利用递归回溯,关键是对返回值的处理非常巧妙!在return后面利用or,如果有一个为True,则返回True,否则返回False.

    from typing import List
    class Solution:
        def canReach(self, arr: List[int], start: int) -> bool:
            n = len(arr)
            def backtrack(i, flag):
                # 如果出界了,或者已经遍历过了,返回False
                if i < 0 or i >= n or flag[i] == 1:
                    return False
                # 如果满足条件,返回True
                if arr[i] == 0:
                    return True
                # 记录遍历过的索引
                flag[i] = 1
                # 有一个分支满足条件,则返回True,结束回溯,否则遍历完所有的.
                return backtrack(i + arr[i], flag) or backtrack(i - arr[i], flag)
            flag = [0 for i in range(n)]
            return backtrack(start, flag)
    View Code

    法三: bfs

    思路: 利用队列实现,每次都将当前位置左右两边满足条件的索引放入队列,直到返回True或队列为空了,返回False.

    from typing import List
    from collections import deque
    class Solution:
        def canReach(self, arr, start):
            n = len(arr)
            q = deque()
            visited = set()
            q.append(start)
            while q:
                # 从队列的左边取数
                ind = q.popleft()
                # 每取一个都放入集合中.
                visited.add(ind)
                # 如果为0,直接返回
                if arr[ind] == 0:
                    return True
                # 遍历索引的左边和右边
                for x in (ind - arr[ind], ind + arr[ind]):
                    # 如果索引在范围内,且没有被遍历过,则加入队列
                    if 0 <= x < n and x not in visited:
                        q.append(x)
            # 如果都没有返回True,则返回False.
            return False
    View Code

    ttt

  • 相关阅读:
    哈夫曼树
    MUI
    mui.init方法配置
    js中如何把字符串转化为对象、数组示例代码
    ( 转 )超级惊艳 10款HTML5动画特效推荐
    ( 转 ) 关于微信公众号,你不知道的15个小技巧
    h5预加载代码
    css3常用动画样式文件move.css
    iphone微信 h5页音乐自动播放
    sshpass: 用于非交互的ssh 密码验证
  • 原文地址:https://www.cnblogs.com/xxswkl/p/12119428.html
Copyright © 2020-2023  润新知