○ 求相邻最近的点
- 注意,在这里首先声明了 m i n = f l o a t ( " i n f " ) min = float("inf") min=float("inf") 这句话的意思是, m i n min min 初始化的值为正无穷。
○ 阶乘
递归法
循环法
- 使用 for 循环
- 使用 while 循环
○ 斐波那契数列
递归法
※ 循环法(这个思路牛逼)
○ 汉诺塔(Hanoi)
-
H
a
n
o
i
(
)
Hanoi()
Hanoi() 函数里面的参数意义分别是:
- n n n:一共有 n n n 个盘子
- a a a:起始的柱子
- b b b:中间的柱子
- c c c:最终的柱子
- 算法解析:
- 如果有 1 1 1 个盘子,那么直接从 a → c a→c a→c;
- 如果有 2 2 2 个盘子,那么需要先把最上面的盘子 a → b a→b a→b, 再把最后一个盘子从 a → c a→c a→c,再把第一个盘子从 b → c b→c b→c
- 如果有 n n n 个盘子,我们应该把整个搬移过程模式化,那就是我们总是试图通过借助柱子 b b b 将上面 n − 1 n-1 n−1 个盘子从 a → b a→b a→b,然后再把最后一个盘子从 a → c a→c a→c,再把上面的 n − 1 n-1 n−1 个盘子从 b → c b→c b→c,而上面 n − 1 n-1 n−1 个盘子的移动过程,我们把他们都可以看做是一个的小汉诺塔问题。这就是解决问题的关键。
- 而问题的出口就是最后一个盘子,当存在唯一一个盘子的时候,它本身就是最后一个盘子,因此直接 a → c a→c a→c 即可,而如果不是一个盘子,我们就需要先挪动上面 n − 1 n-1 n−1 个盘子,再操作最后一个盘子。
- H a n o i ( n , a , b , c ) Hanoi(n,a,b,c) Hanoi(n,a,b,c) 的意思就是:将 n n n 个盘子,从 a a a 借助 b b b 移到 c c c;因此 H a n o i ( n − 1 , a , c , b ) Hanoi(n-1,a,c,b) Hanoi(n−1,a,c,b) 的意思就是:将 n − 1 n-1 n−1 个盘子,从 a a a 借助 c c c 移动到 b b b
○ ※ 零钱问题(递归法)
-
题目描述:给定一个具体数额 amount = 10元,从一个面值 denomination 集合中(6,2, 1)中每次使用一个数字,使得最终能够凑满 10 元钱,问这样的解有多少个。
-
看这个图可能会有助于理解,题目中的关键就在于递归的公式,最后的
return ways(amount - d, denominations) + ways(amount, denominations.difference([d]))
-
前半个公式:
return ways(amount - d, denominations)
表示的是图中红线的部分,第一个 stage 随机选择的面值是 1,那么自然而然下一个 stage 的起始 amount = 10 - 1 = 9;第二个 stage 我们选择的面值是 2,那么下一个 stage 的起始 amount = 9-2 = 7,这个没有任何问题。那为什么这个公式还有后面一半:ways(amount, denominations.difference([d]))
呢??? -
原因就是,如果我们只考虑公式的前半部分,我们最终返回的结果只能包含红线这一条线路;而不能考虑到其他的选择。如果我们看到后面的公式我们就会发现,
ways(amount, denominations.difference([d]))
中,amount 并没有减 d ,而是维持了 amount,而 demomination 的部分却排除了本 stage 中被选择的面值。 -
简单地来说,如果前半部分的公式是不断地向深度搜索一条满足条件的路,那么公式的后半部分表示的,就是在每一步骤的时候,所有并行的可能。当第一个 **stage:10 **已经选择了面值 1,此时的第二个部分的公式就会返回 10 选择面值 8 和 面值 4 的可能并向深度进行探索。
-
如果还没有明白,可以根据下面的图看,会辅助你理解。
-
零钱问题使用递归的方法并不是最高效的,因为他的复杂度是指数型增长的,比较常用的方法是动态规划,后面会涉及
○ 字符串匹配
- 首先在 text 文字中进行的循环次数,不需要将 text 全部进行循环,因为如果 text 包含 pattern,那么最多需要查询的情况就是 text 长度 - pattern 的长度加一次。
- 当 text 中出现了 pattern 的第一个字母就可以开启检测的过程了
- 整个检测过程使用一个 while 或 for 循环来完成,循环的次数是 pattern 的长度次;当然也可以是 pattern 长度- 1 次,这样的话就必须 count 从 1 开始计数(把 pattern[0] = text[i] 这一次也算在其中),即如下图所示