递归和动态规划
parent
b34bc34143
commit
23bf92a1e9
|
@ -1,2 +1,4 @@
|
|||
.venv
|
||||
test/.pytest_cache/
|
||||
.idea
|
||||
test/.pytest_cache/
|
||||
**/__pycache__
|
|
@ -0,0 +1,52 @@
|
|||
"""
|
||||
动态规划的核心:
|
||||
将大问题分解为多个小问题,通过解决一个个小问题,
|
||||
并保存解决每个小问题时的状态最终解决大问题
|
||||
|
||||
动态规划实现找零:
|
||||
1. 先看找零1元需要多少:1
|
||||
2. 找零2元需要多少:两张1元
|
||||
3. 找零3元需要多少:找零2元的结果+找零1元的结果
|
||||
"""
|
||||
|
||||
|
||||
# 动态规划找零
|
||||
def dp_rec_mc1(changes: list[int], cash: int):
|
||||
min_changes = [0 for _ in range(cash + 1)]
|
||||
for i in range(1, cash + 1):
|
||||
min_amount = i
|
||||
for c in filter(lambda x: x <= i, changes):
|
||||
temp_min_amount = 1 + min_changes[i - c]
|
||||
if temp_min_amount < min_amount:
|
||||
min_amount = temp_min_amount
|
||||
|
||||
min_changes[i] = min_amount
|
||||
|
||||
return min_changes[cash]
|
||||
|
||||
|
||||
# 动态规划找零,并保存每一种找零所需的纸币情况
|
||||
def dp_rec_mc2(changes: list[int], cash: int):
|
||||
change_used: dict[int, dict[int, int]] = {}
|
||||
min_amounts = [0 for _ in range(cash + 1)]
|
||||
for i in range(1, cash + 1):
|
||||
min_amount = i
|
||||
changes_less_then_i = filter(lambda x: x <= i, changes)
|
||||
for c in changes_less_then_i:
|
||||
temp_min_amount = 1 + min_amounts[i - c]
|
||||
if temp_min_amount < min_amount:
|
||||
min_amount = temp_min_amount
|
||||
if i - c > 0:
|
||||
change_used[i] = change_used[i - c].copy()
|
||||
if change_used[i].get(c):
|
||||
change_used[i][c] += 1
|
||||
else:
|
||||
change_used[i][c] = 1
|
||||
else:
|
||||
change_used[i] = {c: 1}
|
||||
|
||||
min_amounts[i] = min_amount
|
||||
if min_amount == i:
|
||||
change_used[i] = {1: i}
|
||||
return change_used[cash]
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
class Node:
|
||||
def __init__(self, value: int, children=None):
|
||||
self.value = value
|
||||
self.children = children
|
||||
|
||||
|
||||
nodes1 = Node(1, [Node(2, [Node(4), Node(5)]), Node(3, [Node(6), Node(7)])])
|
||||
|
||||
nodes2 = Node(1, [Node(2, [Node(4), Node(5), Node(10, [Node(19), Node(39), Node(27)])]), Node(3, [Node(6), Node(7)])])
|
||||
|
||||
|
||||
def iter_tree(node: Node):
|
||||
res = [node.value]
|
||||
|
||||
def recursive(nodes: list[Node], temp_res: list[int]):
|
||||
temp = []
|
||||
for _node in nodes:
|
||||
temp_res.append(_node.value)
|
||||
if _node.children:
|
||||
temp.extend(_node.children)
|
||||
if len(temp) > 0:
|
||||
recursive(temp, temp_res)
|
||||
|
||||
if node.children:
|
||||
recursive(node.children, res)
|
||||
|
||||
return res
|
|
@ -0,0 +1,49 @@
|
|||
from typing import Self
|
||||
|
||||
|
||||
class SinglyNode:
|
||||
def __init__(self, value, nex: Self | None):
|
||||
self.value = value
|
||||
self.next = nex
|
||||
|
||||
def __repr__(self):
|
||||
return f'Node({self.value})'
|
||||
|
||||
class SinglyLinkList:
|
||||
|
||||
__string = ''
|
||||
|
||||
def __init__(self):
|
||||
self.size = 0
|
||||
self.head: SinglyNode | None = None
|
||||
|
||||
def __repr__(self):
|
||||
return self.__string
|
||||
|
||||
def is_empty(self) -> bool:
|
||||
return self.size == 0
|
||||
|
||||
# 新节点总是添加到头部
|
||||
def push(self, value):
|
||||
if self.head is None:
|
||||
self.__string = f'{value} -> None'
|
||||
else:
|
||||
self.__string = f'{value} -> ' + self.__string
|
||||
node = SinglyNode(value, self.head)
|
||||
self.head = node
|
||||
self.size += 1
|
||||
|
||||
def pop(self) -> SinglyNode:
|
||||
head = self.head
|
||||
node = self.head.next
|
||||
self.head = node
|
||||
return head
|
||||
|
||||
def peek(self):
|
||||
return self.head.value
|
||||
|
||||
def iter(self):
|
||||
cur = self.head
|
||||
while cur:
|
||||
yield cur.value
|
||||
cur = cur.next
|
|
@ -0,0 +1,61 @@
|
|||
"""
|
||||
递归三定律:
|
||||
1 递 归 算 法 必 须 具 有 基 本 情 况
|
||||
2 递 归 算 法 必 须 向 基 本 情 况 靠 近
|
||||
3 递 归 算 法 必 须 以 递 归 方 式 调 用 自 身
|
||||
"""
|
||||
|
||||
def recursive_sum(nums: list):
|
||||
if 1 == len(nums):
|
||||
return nums[0]
|
||||
|
||||
return nums[0] + recursive_sum(nums[1:])
|
||||
|
||||
|
||||
# 使用递归的方式实现进制转换
|
||||
def recursive_num_conversion(num: int) -> str:
|
||||
if num == 0:
|
||||
return ''
|
||||
|
||||
return recursive_num_conversion(num // 2) + str(num % 2)
|
||||
|
||||
|
||||
# 找零问题:类似贪婪,经量找出最少纸币搭配
|
||||
def rec_mc1(changes: list[int], cash: int):
|
||||
# 全用1元纸币时最少找零数
|
||||
min_amount = cash
|
||||
|
||||
try:
|
||||
if changes.index(cash):
|
||||
return 1
|
||||
except Exception as e:
|
||||
for c in changes:
|
||||
# cash - c,表示使用了一张面额为c的来找零,所以需要+1
|
||||
num = 1 + rec_mc1(changes, cash-c)
|
||||
|
||||
if num < min_amount:
|
||||
min_amount = num
|
||||
|
||||
return min_amount
|
||||
|
||||
|
||||
def rec_mc2(changes: list[int], cash: int, min_changes: int,):
|
||||
min_amount = cash
|
||||
|
||||
try:
|
||||
if changes.index(cash):
|
||||
min_changes[cash] = 1
|
||||
return 1
|
||||
except Exception as e:
|
||||
if min_changes[cash] > 0:
|
||||
return min_changes[cash]
|
||||
else:
|
||||
for c in changes:
|
||||
num = 1 + rec_mc2(changes, cash - c, min_changes)
|
||||
|
||||
if num < min_amount:
|
||||
min_amount = num
|
||||
min_changes[cash] = min_amount
|
||||
|
||||
return min_amount
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
from dynamic_programming.dynamic_programming import *
|
||||
|
||||
|
||||
def test_dp_rec_mc1():
|
||||
cash = 49
|
||||
changes = [1, 5, 10, 20, 50]
|
||||
assert 7 == dp_rec_mc1(changes, cash)
|
||||
|
||||
|
||||
def test_dp_rec_mc2():
|
||||
cash = 49
|
||||
changes = [1, 5, 10, 20, 50]
|
|
@ -0,0 +1,12 @@
|
|||
from link_list.singly_link import SinglyLinkList
|
||||
|
||||
def test_singly_link():
|
||||
link_list = SinglyLinkList()
|
||||
link_list.push(1)
|
||||
link_list.push(2)
|
||||
link_list.push(3)
|
||||
link_list.push(4)
|
||||
|
||||
assert 4 == link_list.peek()
|
||||
assert 4 == link_list.size
|
||||
assert "4 -> 3 -> 2 -> 1 -> None" == repr(link_list)
|
|
@ -0,0 +1,10 @@
|
|||
from recursive.recursive import *
|
||||
|
||||
|
||||
def test_recursive_sum():
|
||||
nums = [1, 2, 3]
|
||||
assert 6 == recursive_sum(nums)
|
||||
|
||||
def test_recursive_num_conversion():
|
||||
num = 10
|
||||
assert '1010' == recursive_num_conversion(num)
|
Loading…
Reference in New Issue