贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找

本文内容来自公众号 labuladong、LeetCode官网、CSDN" 执 梗 "博主文章“蓝桥杯真题五”、廖雪峰的Python教程、快速幂算法参考的博主文章、全排列参考的博主文章,作者只是搬运和整理

一、贪心算法

无重叠区间

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第1张图片

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)


用最少数量的箭引爆气球

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第2张图片

 贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第3张图片

        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)

二、深度优先搜索

课程表

本题同样可以使用深度优先搜索,但使用广度优先搜索的题解更易理解

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第4张图片

 贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第5张图片

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教程

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第6张图片

另外的,普通的 list 的 pop 方法 list.pop() 表示移除列表中的一个元素,使用下表索引,默认为最后一个元素

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第7张图片

 三、快速幂算法

 贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第8张图片

 题目为ACM题目,一看很简单,但当指数很大时,如100,简单的求指数的结果就会溢出

方法一:取模运算

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第9张图片

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第10张图片

 方法二:快速幂算法:最后求出的幂结果实际上就是在变化过程中所有当指数为奇数时底数的乘积

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取整的作用

 四、全排列实现

  贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第11张图片

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第12张图片

 递归实现有字符串和列表之分

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第13张图片

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)

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第14张图片

五、二分查找

x的平方根

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第15张图片

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)

最长递增子序列

在文章 动态规划题目 有提到此题其中之一解法为动态规划,还有解法为贪心+二分查找

贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第16张图片

 贪心算法(区间调度)、广度优先搜索(简单模式)、快速幂算法、全排列实现、二分查找_第17张图片

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))

你可能感兴趣的:(刷题,python,动态规划,贪心算法,leetcode,宽度优先)