我正在尝试解决leetcode上的以下问题:硬币兑换2
输入:金额=5,硬币=[1,2,5]输出:4说明:有四种方法来弥补金额:
5=5
5=2 2 1
5=2 1 1 1
5=1 1 1 1 1
我试图实现一个迭代的解决方案,本质上模拟/模仿递归使用堆栈。我已经设法实现了它,解决方案有效,但它超过了时间限制。
我注意到递归解决方案利用记忆进行优化。我也想在我的迭代解决方案中包含这一点,但我不知道如何继续。
到目前为止,我的解决方案是:
# stack to simulate recursion
stack = []
# add starting indexes and sum to stack
#Tuple(x,y) where x is sum, y is index of the coins array input
for i in range(0, len(coins)):
if coins[i]<=amount:
stack.append((coins[i], i))
result = 0
while len(stack)!=0:
c = stack.pop()
currentsum = c[0]
currentindex = c[1]
# can't explore further
if currentsum >amount:
continue
# condition met, increment result
if currentsum == amount:
result = result+1
continue
# add coin at current index to sum if doesn't exceed amount (append call to stack)
if (currentsum+coins[currentindex])<=amount:
stack.append((currentsum+coins[currentindex], currentindex))
#skip coin at current index (append call to stack)
if (currentindex+1)<=len(coins)-1:
stack.append((currentsum, currentindex+1))
return result
我已经尝试使用字典记录附加到堆栈如下:
#if the call has not already happened, add to dictionary
if dictionary.get((currentsum, currentindex+1), None) == None:
stack.append((currentsum, currentindex+1))
dictionary[currentsum, currentindex+1)] = 'visited'
例如,如果进行了sum=2和coin数组index=1的调用(2,1),我将其附加到字典中。如果再次遇到相同的调用,我不会再次追加它。但是,它不起作用,因为不同的组合可以有相同的总和和索引。
不管怎样,我可以在上面的迭代解决方案中加入记忆化。我想这样做,使它在功能上与递归解决方案相同。
我设法找到了解决办法。本质上,我使用了后序遍历,并使用状态变量来记录当前调用所处的递归阶段。在舞台上,我在自上而下之后,成功地做到了自下而上。
我提出的解决方案如下:
def change(self, amount: int, coins: List[int]) -> int:
if amount<=0:
return 1
if len(coins) == 0:
return 0
d= dict()
#currentsum, index, instruction
coins.sort(reverse=True)
stack = [(0, 0, 'ENTER')]
calls = 0
while len(stack)!=0:
currentsum, index, instruction = stack.pop()
if currentsum == amount:
d[(currentsum, index)] = 1
continue
elif instruction == 'ENTER':
stack.append((currentsum, index, 'EXIT'))
if (index+1)<=(len(coins)-1):
if d.get((currentsum, index+1), None) == None:
stack.append((currentsum, index+1, 'ENTER'))
newsum = currentsum + coins[index]
if newsum<=amount:
if d.get((newsum, index), None) == None:
stack.append((newsum, index, 'ENTER'))
elif instruction == 'EXIT':
newsum = currentsum + coins[index]
left = 0 if d.get((newsum, index), None) == None else d.get((newsum, index))
right = 0 if d.get((currentsum, index+1), None) == None else d.get((currentsum, index+1))
d[(currentsum, index)] = left+right
calls = calls+1
print(calls)
return d[(0,0)]
本文向大家介绍C++实现递归函数的方法,包括了C++实现递归函数的方法的使用技巧和注意事项,需要的朋友参考一下 递归函数通俗来讲就是自己调用自己本身。这样有很大的好处,代码很方便简洁,把复杂的有规律的运算交给计算机去做。 1、首先定义问题。递归函数(recursion)需要设置一个函数,然后再可以循环往复的执行下去。 2、把问题换成公式。 如把阶乘之和定义为f(n)=n*f(n-1)。也就是说n*
我在scheme中构建了一个递归函数,它将在一些输入上重复给定的函数f,n次。 我需要用尾递归构建这个函数的迭代版本,如果我正确理解尾递归,我认为我做得对。 我的问题是,这真的是迭代的吗?我相信我已经使用尾部递归正确地构建了它,但从技术上讲,它仍然将一系列操作推迟到count=0,在这里,它执行叠加的任意多个组合。
本文向大家介绍php使用递归函数实现数字累加的方法,包括了php使用递归函数实现数字累加的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php使用递归函数实现数字累加的方法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的php程序设计有所帮助。
本文向大家介绍Python实现链表反转的方法分析【迭代法与递归法】,包括了Python实现链表反转的方法分析【迭代法与递归法】的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python实现链表反转的方法。分享给大家供大家参考,具体如下: Python实现链表反转 链表反转(while迭代实现): 链表的反转引入一个cur_node变量,表示当前节点;同时需要引入一个变量new_link表
如果说在任何地方都使用递归,那么可以使用for循环,对吗?如果递归通常比较慢,那么将其用于循环迭代的技术原因是什么? 如果总是可以将递归转换为for循环,那么有经验法则吗?