本文内容来自公众号 labuladong、LeetCode官网、CSDN" 执 梗 "博主文章“蓝桥杯真题五”、廖雪峰的Python教程、快速幂算法参考的博主文章、全排列参考的博主文章,作者只是搬运和整理
一、贪心算法
无重叠区间
class Solution: def eraseOverlapIntervals(self, intervals: List[List[int]]): if not intervals: return(0) intervals.sort(key=lambda x:x[1]) n=len(intervals) ans=1 right=intervals[0][1] for i in range(1,n): if intervals[i][0]>=right: ans+=1 right=intervals[i][1] return(n-ans)用最少数量的箭引爆气球
points.sort(key=lambda x:x[1]) n = len(points) right=points[0][1] count=1 for i in range(1,n): if points[i][0]>right: count+=1 right=points[i][1] return(count)
二、深度优先搜索
课程表
本题同样可以使用深度优先搜索,但使用广度优先搜索的题解更易理解
class Solution: def canFinish(self, numCourses: int, prerequisites: List[List[int]]): # 存储有向图 edges = collections.defaultdict(list) # 存储每个节点的入度 indeg = [0] * numCourses # 存储答案 result = list() for info in prerequisites: edges[info[1]].append(info[0]) indeg[info[0]] += 1 # 将所有入度为 0 的节点放入队列中 q = collections.deque([u for u in range(numCourses) if indeg[u] == 0]) while q: # 从队首取出一个节点 u = q.popleft() # 放入答案中 result.append(u) for v in edges[u]: indeg[v] -= 1 # 如果相邻节点 v 的入度为 0,就可以选 v 对应的课程了 if indeg[v] == 0: q.append(v) if len(result) != numCourses: return False return True极相似的题目课程表||,只需将输出变为 result
代码中涉及的 collections模块下的deque和defaultdict方法,下面来自廖雪峰的Python教程
另外的,普通的 list 的 pop 方法 list.pop() 表示移除列表中的一个元素,使用下表索引,默认为最后一个元素
三、快速幂算法
题目为ACM题目,一看很简单,但当指数很大时,如100,简单的求指数的结果就会溢出
方法一:取模运算
方法二:快速幂算法:最后求出的幂结果实际上就是在变化过程中所有当指数为奇数时底数的乘积
long long fastPower(long long base, long long power) { long long result = 1; while (power > 0) { if (power & 1) {//此处等价于if(power%2==1) result = result * base % 1000; } power >>= 1;//此处等价于power=power/2 base = (base * base) % 1000; } return result; }
优化方面:(1)位运算(奇偶判断): power & 1 当power为奇数,结果为1,反之为0
(2)power >>= 1 位运算,起到除2取整的作用
四、全排列实现
递归实现有字符串和列表之分
def permutation_sub(prefix_str,suffix_str,result): if len(suffix_str) == 0: # 当后缀为空时,即产生一个结果 result.append(prefix_str) for s in suffix_str: permutation_sub(prefix_str + s, suffix_str.replace(s,''), result) def permutation(input_str): perm = [] permutation_sub('',input_str,perm) return perm if __name__ == "__main__": for x in permutation('abcd'): print(x)
列表
def permutation_sub(ls,start,result): if start == len(ls) - 1: result.append(list(ls)) return for i in range(start,len(ls)): ls[i],ls[start] = ls[start],ls[i] # 后续元素依次与start交换,作为领导元素 permutation_sub(ls,start + 1,result) ls[i],ls[start] = ls[start],ls[i] # 再次交换,复原上次结构,方便进行下个元素的交换 def permutation(ls): perm = [] permutation_sub(ls,0,perm) return perm if __name__ == "__main__": for x in permutation(['a','b','c','d']): print(x)
五、二分查找
x的平方根
class Solution: def mySqrt(self, x: int): l,r,m=0,x,-1 while l<=r: mid=(l+r)//2 if mid*mid<=x: m=mid l=mid+1 else: r=mid-1 return(m)
最长递增子序列
在文章 动态规划题目 有提到此题其中之一解法为动态规划,还有解法为贪心+二分查找
class Solution: def lengthOfLIS(self, nums: List[int]): d=[] for n in nums: if not d or n>d[-1]: d.append(n) else: l,r=0,len(d)-1 loc=r while l<=r: mid=(l+r)//2 if d[mid]>=n: loc=mid r=mid-1 else: l=mid+1 d[loc]=n return(len(d))