蓝桥杯常考知识点有枚举模拟,数论,动态规划,贪心算法,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|
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|
二、数论
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
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