【问题标题】:Frog Jump Memoization(Python)蛙跳记忆(Python)
【发布时间】:2021-01-07 20:37:05
【问题描述】:

下面是问题描述,然后是使用 Python 的递归解决方案。 该解决方案效率低下。我知道使用记忆,我们可以改进这个解决方案。 我也在 StackOverflow 上遇到过类似的问题,但我无法找到解决方案。我对记忆技术相当陌生。 如果有人可以帮助我解决使用 memoization 的问题,那将非常有帮助。

问题描述: 一只青蛙正在过河。河流被分成若干个单元,每个单元处可能有也可能没有石头。青蛙可以跳上石头,但不能跳入水中。

给定一个按升序排列的石头位置列表(以单位为单位),确定青蛙是否可以通过降落在最后一块石头上过河。最初,青蛙在第一块石头上,并假设第一次跳跃必须是 1 个单位。

如果青蛙的最后一次跳跃是 k 个单位,那么它的下一次跳跃必须是 k - 1、k 或 k + 1 个单位。青蛙只能往前跳。

Examples

以下是我使用递归(Python)的解决方案。

class Solution:
    def canCross(self, stones: List[int]) -> bool:
            return self.helper(stones[0],stones,1)
            
    def helper(self,curr,stones,k):
        if curr+k == stones[-1]:
            return True
        
        if not curr+k in stones or k<=0: 
            return False
        else:
            curr = curr+k 
            return self.helper(curr,stones,k-1)  or self.helper(curr,stones,k) or self.helper(curr,stones,k+1)

【问题讨论】:

    标签: python memoization


    【解决方案1】:

    这里出现的速度更快memo 版本,它比以前的版本更快。它大约快 50%...

    class Solution:
        """
        """
        def canCross(self, stones: List[int]) -> bool:
            self.target = stones[-1]
            stones = set(stones)
            return self.dfs(stones, 0, 0, {})
    
        def dfs(self, stones, cur, k, memo):
            if cur == self.target:
                return True
            if (cur, k) in memo:
                return memo[(cur, k)]
            for nxt in [k-1, k, k+1]:
                if nxt > 0 and cur + nxt in stones:
                    if self.dfs(stones, cur+nxt, nxt, memo):
                        memo[(cur, k)] = True
                        return True
            memo[(cur, k)] = False
            return False
    

    【讨论】:

    • 非常感谢您的帮助,@Daniel Hao。我尝试了上述解决方案,我同意它比以前的版本快得多。
    【解决方案2】:

    @克里希纳,

    请试试这个memo 版本,看看是否加快了速度。

    
         def canCross(self, stones: List[int]) -> bool:
             if stones[1] != 1:
                return False
             d = {x: set() for x in stones}
             d[1].add(1)
             for x in stones[:-1]:
                 for j in d[x]:
                     for k in range(j-1, j+2):
                         if k > 0 and x+k in d:
                             d[x+k].add(k)
             return bool(d[stones[-1]])
    

    【讨论】:

      【解决方案3】:

      functools 装饰器,用于记忆类中的方法:

      from functools import cached_property
      
      class Solution:
          def canCross(self, stones: List[int]) -> bool:
                  return self.helper(stones[0],stones,1)
          
          @cached_property
          def helper(self,curr,stones,k):
              if curr+k == stones[-1]:
                  return True
              
              if not curr+k in stones or k<=0: 
                  return False
              else:
                  curr = curr+k 
                  return self.helper(curr,stones,k-1)  or self.helper(curr,stones,k) or self.helper(curr,stones,k+1)
      
      

      【讨论】:

        猜你喜欢
        • 2013-05-04
        • 1970-01-01
        • 2014-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-24
        相关资源
        最近更新 更多