Python真题练习6(蓝桥杯常考知识点)

蓝桥杯常考知识点有枚举模拟,数论,动态规划,贪心算法,BFS和DFS

题目均来自力扣

一、模拟

下面两题模板:

        1.模拟前的准备

                判断矩阵:有时不定也许是数组,储存访问过的点,初始设置为未访问过;当然第2题,可以不设置判断矩阵,这是因为储存答案的矩阵的初始化就与要添加的数是可以区分的,本身就可以做出判断

                方向数组:根据题目要求来设置,本题要求顺时针改变方向,就让方向数组的四个方向按照顺时针来存储,每次要求改变方向时就可以用取模 direction=(direction+1)%4 来满足

                结束标志:最初我的想法是如若判断矩阵全部被访问就可以结束,怎样实现呢,就是一个点的四个方向的点都被访问时停止即可(很容易知道在未将全部点都走过时,任何一个点总会有一个方向的点未被访问过),但较为复杂,这里就可以用走的点的数量与所有点做判断即可,或者走 一个矩阵全部的点的数目 即可,就是 for i in range(num): 

                结果:储存结果的列表或二维列表

                初始坐标及初始方向

        2.模拟开始,走完所有步数即可

                储存该步结果

                设置已访问

                判断下一步是否合法(在矩阵范围内,未访问),不合法的改变方向

                循环,走下一个点

1.螺旋矩阵

class Solution:
    def spiralOrder(self, matrix: List[List[int]]):
        if not matrix or not matrix[0]:
            return list()
        row=len(matrix)
        column=len(matrix[0])
        #判断矩阵
        judge_matrix=[[False for _ in range(column)] for _ in range(row)]
        #方向数组
        Move=[[0,1],[1,0],[0,-1],[-1,0]]
        #结束标志:每走一步计数直至走完全部
        num=row*column
        #结果
        ans=[0]*num
        #初始坐标及初始方向
        x,y,direction=0,0,0
        for i in range(num):
            ans[i]=matrix[x][y]
            judge_matrix[x][y]=True
            next_x,next_y=x+Move[direction][0],y+Move[direction][1]
            #只有当三个并列条件同时满足时,方向才不会变,但无论方向变与否,在未访问过所有点前,坐标都会加上Move中的一个的
            #而方向改变的条件较多,于是取反,将方向改变的条件写上
            if not (0<=next_x<row and 0<=next_y<column and not judge_matrix[next_x][next_y]):
                direction=(direction+1)%4
            x+=Move[direction][0]
            y+=Move[direction][1]
        return(ans)

2.螺旋矩阵||

class Solution:
    def generateMatrix(self, n: int):
        row=n
        column=n
        #判断矩阵,此时判断矩阵可有可无,由于添加的数均为正整数,而ans初始设置均为0,则若不为0,说明已经访问过了
        # judge_matrix=[[False for _ in range(column)] for _ in range(row)]
        #方向数组
        Move=[[0,1],[1,0],[0,-1],[-1,0]]
        #结束标志:每走一步计数直至走完全部
        num=n*n
        #结果
        ans=[[0 for _ in range(column)] for _ in range(row)]
        #初始坐标及初始方向
        x,y,direction=0,0,0
        for i in range(num):
            ans[x][y]=i+1
            # judge_matrix[x][y]=True
            next_x,next_y=x+Move[direction][0],y+Move[direction][1]
            if not (0<=next_x<row and 0<=next_y<column and ans[next_x][next_y]==0):
                direction=(direction+1)%4
            x+=Move[direction][0]
            y+=Move[direction][1]
        return(ans)

二、数论

1.计数质数

class Solution:
    def countPrimes(self, n: int):
        ans=0
        isPrime=[1]*n #判断是否为质数,质素为1,合数为0
        for i in range(2,n):
            if isPrime[i]:
                ans+=1
                if i*i<n:
                    #如果一个数为质数,那么其的倍数是合数
                    for j in range(i*i,n,i):
                        isPrime[j]=0
        return(ans) 

2.快乐数

class Solution:
    def isHappy(self, n: int):
        #求一个数的‘下一个数’,就是各个位数的平方和
        def get_next(n):
            num=0
            while n!=0:
                n,m=divmod(n,10)
                num+=m*m
            return(num)
        aset=set()
        #一个数通过上面的操作要么最终变成1,要么会陷入循环,若循环再次同样的数时就结束
        while n!=1 and n not in aset:
            aset.add(n)
            n=get_next(n)
        return n==1

三、动态规划

1.打家劫舍

class Solution:
    def rob(self, nums: List[int]):
        n=len(nums)
        #dp[i]表示在前i个房屋中偷盗的最大金额
        dp=[0]*(n+1)
        dp[0],dp[1]=0,nums[0]
        for i in range(2,n+1):
            dp[i]=max(dp[i-1],dp[i-2]+nums[i-1])
        return(dp[n])

2.最大正方形

class Solution:
    def maximalSquare(self, matrix: List[List[str]]):
        row=len(matrix)
        column=len(matrix[0])
        maxSize=0
        dp=[[0]*column for _ in range(row)]
        #dp[i][j]表示以第i行第j列为右下角的正方形的最大边长
        for i in range(row):
            for j in range(column):
                if matrix[i][j]=='1':
                    if i==0 or j==0:
                        dp[i][j]=1
                    else:
                        dp[i][j]=min(dp[i][j-1],dp[i-1][j],dp[i-1][j-1])+1
                    maxSize=max(maxSize,dp[i][j])
        return(maxSize**2)

四、贪心算法

1.种花问题

class Solution:
    def canPlaceFlowers(self, flowerbed: List[int], n: int):
        flowerbed=[0]+flowerbed+[0]
        m=len(flowerbed)
        for i in range(1,m-1):
            if sum(flowerbed[i-1:i+2])==0:
                n-=1
                flowerbed[i]=1
            if n<=0:
                return True
        return False

2.买卖股票的最佳时机||

class Solution:
    def maxProfit(self, prices: List[int]):
        n=len(prices)
        dp=[[0,0] for _ in range(n+1)]
        #dp[i][0]表示第i天不持有股票的最大利润,dp[i][1]表示第i天持有股票的最大利润
        dp[1][1]=-prices[0]
        for i in range(2,n+1):
            dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i-1])
            dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i-1])
        return(dp[n][0])

五、BFS和DFS

课程表

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值