递归
通过LeetCode上【70. 爬楼梯】学习(建议)
方法一:斐波拉切(用时28 ms,击败了99.36%的用户)
观察发现是斐波拉切数,代码如下1
2
3
4
5
6
7
8
9
10
11
12
13class Solution(object):
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
if n == 1:
return 1
else:
ans = [1, 1]
for i in range(2, n + 1):
ans.append(ans[i - 2] + ans[i - 1])
return ans[-1]
方法二:使用递归(超时)
这道题自顶向下的思考:如果要爬到
n
台阶,有两种可能性:
- 在
n-1
的台阶处爬一层台阶- 在
n-2
的台阶处爬两层台阶继续向下延伸思考,
到达每一次层一共有几种方法
这个问题就变成了2个子问题:
- 到达
n-1
层台阶有几种方法- 到达
n-2
层台阶有几种方法之后对返回子问题之和即可。
因为递归的时候出现了很多次重复的运算。如爬n-2层的计算出现了2次,这种重复计算随着input的增大,会出现的越来越多,时间复杂度也会将以指数的级别上升。
1 | class Solution(object): |
方法三:动态规划
优化方法二,将之前的计算好了的结果存起来,之后如果遇到重复计算直接调用结果,效率将会从之前的指数时间复杂度,变成O(N)的时间复杂度。1
2
3
4
5
6
7
8class Solution(object):
def climbStairs(self, n):
if n == 1: return 1
res = [0 for i in range(n)]
res[0], res[1] = 1, 2
for i in range(2, n):
res[i] = res[i-1] + res[i-2]
return res[-1]
参考:https://leetcode.com/problems/climbing-stairs/discuss/163347/Python-3000DP-or-tm
回溯
利用回溯算法求解八皇后问题
1 | def place(x, k): #判断是否冲突 |
简洁解法可参考: https://blog.csdn.net/handsomekang/article/details/41308993 (简洁,用一维数组表达坐标)
利用回溯算法求解 0-1 背包问题
1 | #n个物体的重量(w[0]无用) |
分治
利用分治算法求一组数据的逆序对个数
1 | def merge_sort(data): |
动态规划
0-1 背包问题
1 | def bag(space,n,costs,values): |
最小路径和(详细可看 Minimum Path Sum)
1 | def minPathSum(self, grid): |
编程实现莱文斯坦最短编辑距离
dp[i][j]表示word1[0…i-1]到word2[0…j-1]的编辑距离。而dp[i][0]显然等于i,因为只需要做i次删除操作就可以了。同理dp[0][i]也是如此,等于i,因为只需做i次插入操作就可以了。dp[i-1][j]变到dp[i][j]需要加1,因为word1[0…i-2]到word2[0…j-1]的距离是dp[i-1][j],而word1[0…i-1]到word1[0…i-2]需要执行一次删除,所以dp[i][j]=dp[i-1][j]+1;同理dp[i][j]=dp[i][j-1]+1,因为还需要加一次word2的插入操作。如果word[i-1]==word[j-1],则dp[i][j]=dp[i-1][j-1],如果word[i-1]!=word[j-1],那么需要执行一次替换replace操作,所以dp[i][j]=dp[i-1][j-1]+1
1 | class Solution: |
编程实现查找两个字符串的最长公共子序列
方法一:递归
1 | def lcs(X, Y, m, n): |
方法二:动态规划
1 | def lcs(X , Y): |
编程实现一个数据序列的最长递增子序列
方法一:二分
1 | class Solution(object): |
方法二:动态规划
1 | class Solution(object): |
对应的 LeetCode 练习题
实战递归:完成Leetcode上的Letter Combinations of a Phone Number(17)及permutations(46)
(保留往期第六天任务)
实战DP:完成0-1背包问题实现(自我实现)及Leetcode上Palindrome Partitioning II(132)
补充题目:leetcode198 House Robber
(保留往期第七天任务)
Regular Expression Matching(正则表达式匹配)
英文版:https://leetcode.com/problems/regular-expression-matching/
中文版:https://leetcode-cn.com/problems/regular-expression-matching/
Minimum Path Sum(最小路径和)
英文版:https://leetcode.com/problems/minimum-path-sum/
中文版:https://leetcode-cn.com/problems/minimum-path-sum/
Coin Change (零钱兑换)
英文版:https://leetcode.com/problems/coin-change/
中文版:https://leetcode-cn.com/problems/coin-change/
Best Time to Buy and Sell Stock(买卖股票的最佳时机)
英文版:https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
中文版:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/
Maximum Product Subarray(乘积最大子序列)
英文版:https://leetcode.com/problems/maximum-product-subarray/
中文版:https://leetcode-cn.com/problems/maximum-product-subarray/
Triangle(三角形最小路径和)