记录 22.9.24 竞赛1~3
LCP竞赛 五道题拿下两道 继续努力!
1. 气温变化趋势
题目链接:1. 气温变化趋势
题目大意:力扣城计划在两地设立「力扣嘉年华」的分会场,气象小组正在分析两地区的气温变化趋势,对于第 i ~ (i+1) 天的气温变化趋势,将根据以下规则判断:
- 若第 i+1 天的气温 高于 第 i 天,为 上升 趋势
- 若第 i+1 天的气温 等于 第 i 天,为 平稳 趋势
- 若第 i+1 天的气温 低于 第 i 天,为 下降 趋势
已知 temperatureA[i] 和 temperatureB[i] 分别表示第 i 天两地区的气温。
组委会希望找到一段天数尽可能多,且两地气温变化趋势相同的时间举办嘉年华活动。请分析并返回两地气温变化趋势相同的最大连续天数。
即最大的 n,使得第 i~i+n 天之间,两地气温变化趋势相同
例如:
temperatureA = [21,18,18,18,31]
temperatureB = [34,32,16,16,17]
输出:2
解释:如下表所示, 第 2~4 天两地气温变化趋势相同,且持续时间最长,因此返回 4-2=2
提示:
- 2 <= temperatureA.length == temperatureB.length <= 1000
- -20 <= temperatureA[i], temperatureB[i] <= 40
解题思路: 这道题 刚看到的时候有些懵,不过按照题意一步一步处理即可! 读懂题意是关键所在:
- 对两个数组进行 上升、平稳、下降 三个程度的判断,可以分别用 1,0,-1 来表示;
- 得到数组后 使用 双指针进行连续区域 的判断即可
- 此题不难,本次做题后最深的感受就是一定要快速地摸清楚作者想说什么,然后下手就可以快一些,实现起来并不难,一定要有信心!
class Solution:
def judge(self,nums: List[int]) -> None:
n = len(nums)
l = [0]*(n-1)
for i in range(1,n):
if nums[i]>nums[i-1]:
l[i-1] = 1
if nums[i]<nums[i-1]:
l[i-1] = -1
return l
def temperatureTrend(self, tA: List[int], tB: List[int]) -> int:
l1,l2 = self.judge(tA),self.judge(tB)
print(l1,l2)
n = len(l1)
ans,i = 0,0
while i<n:
j = i
while j<n and l1[j] == l2[j]:
j += 1
ans =max(ans,j-i)
i = j+1
return ans
2. 交通枢纽
题目链接:2. 交通枢纽
题目大意:为了缓解「力扣嘉年华」期间的人流压力,组委会在活动期间开设了一些交通专线。path[i] = [a, b] 表示有一条从地点 a通往地点 b 的 单向 交通专线。
若存在一个地点,满足以下要求,我们则称之为 交通枢纽:
- 所有地点(除自身外)均有一条 单向 专线 直接 通往该地点;
- 该地点不存在任何 通往其他地点 的单向专线。
请返回交通专线的 交通枢纽。若不存在,则返回 -1。
注意:
- 对于任意一个地点,至少被一条专线连通。
例如:
输入:path = [[0,1],[0,3],[1,3],[2,0],[2,3]]
输出:3
解释:如下图所示:
地点 0,1,2 各有一条通往地点 3 的交通专线,
且地点 3 不存在任何通往其他地点的交通专线。
输入:path = [[0,3],[1,0],[1,3],[2,0],[3,0],[3,2]]
输出:-1
解释:如下图所示:不存在满足 交通枢纽 的地点。
提示:
- 1 <= path.length <= 1000
- 0 <= path[i][0], path[i][1] <= 1000
- path[i][0] 与 path[i][1] 不相等
解题思路: 这是道 图 题 不过在此没有用图的知识,思考了很久,主要思路就是:
- 确定可以进行判断的点,即 该点仅作为接受点不进行发射,即 该点仅位于path[][1]的位置,未在path[][0]的位置出现;
- 统计path中所有的点个数,判断该点是否承接除自身之外所有点。
-
这里提供学习 小羊肖恩 大佬的图解代码 。
-
方法(一)
class Solution:
def transportationHub(self, path: List[List[int]]) -> int:
l1,l2 = set(),set()
for a,b in path:
l1.add(a)
l2.add(b)
l3 = [num for num in l2 if num not in l1]
if len(l3)==0: return -1
n = len(l1)+len(l3)
# print(l1,l2,l3,n)
for i in l3:
tmp = 0
for a,b in path:
if b == i: tmp+=1
if tmp == n-1: return i
return -1
方法(二)
class Solution:
def transportationHub(self, path: List[List[int]]) -> int:
visited = set()
inv,outv = collections.defaultdict(set),collections.defaultdict(set)
for x,y in path:
visited.add(x)
visited.add(y)
inv[y].add(x)
outv[x].add(y)
n = len(visited)-1
for i in visited:
if len(inv[i]) == n and len(outv[i])== 0:
return i
return -1
3. 弹珠游戏
题目链接:3. 弹珠游戏
题目大意:欢迎各位来到「力扣嘉年华」,接下来将为各位介绍在活动中广受好评的弹珠游戏。N*M 大小的弹珠盘的初始状态信息记录于一维字符串型数组 plate 中,数组中的每个元素为仅由 “O”、“W”、“E”、“.” 组成的字符串。其中:
- “O” 表示弹珠洞(弹珠到达后会落入洞中,并停止前进);
- “W” 表示逆时针转向器(弹珠经过时方向将逆时针旋转 90 度);
- “E” 表示顺时针转向器(弹珠经过时方向将顺时针旋转 90 度);
- “.” 表示空白区域(弹珠可通行)。
游戏规则要求仅能在边缘位置的 空白区域 处(弹珠盘的四角除外)沿 与边缘垂直 的方向打入弹珠,并且打入后的每颗弹珠最多能 前进 num 步。请返回符合上述要求且可以使弹珠最终入洞的所有打入位置。你可以 按任意顺序 返回答案。
注意:
- 若弹珠已到达弹珠盘边缘并且仍沿着出界方向继续前进,则将直接出界。
例如:
输入:
num = 4
plate = ["..E.",".EOW","..W."]
输出:[[2,1]]
解释:在 [2,1] 处打入弹珠,弹珠前进 1 步后遇到转向器,前进方向顺时针旋转 90 度,再前进 1 步进入洞中。
输入:
num = 5
plate = [".....","..E..",".WO..","....."]
输出:[[0,1],[1,0],[2,4],[3,2]]
解释:
在 [0,1] 处打入弹珠,弹珠前进 2 步,遇到转向器后前进方向逆时针旋转 90 度,再前进 1 步进入洞中。
在 [1,0] 处打入弹珠,弹珠前进 2 步,遇到转向器后前进方向顺时针旋转 90 度,再前进 1 步进入洞中。
在 [2,4] 处打入弹珠,弹珠前进 2 步后进入洞中。
在 [3,2] 处打入弹珠,弹珠前进 1 步后进入洞中。
输入:
num = 3
plate = [".....","....O","....O","....."]
输出:[]
解释:
由于弹珠被击中后只能前进 3 步,且不能在弹珠洞和弹珠盘四角打入弹珠,故不存在能让弹珠入洞的打入位置。
提示:
- 1 <= num <= 10^6
- 1 <= plate.length, plate[i].length <= 1000
- plate[i][j] 仅包含 “O”、“W”、“E”、“.”
解题思路:
- 这道题委实让人心酸 写到最后了 把回溯的具体用法给忘了,没有用
return helper(dir,i,j,k-1)
好遗憾啊! 这次竞赛也就停步于第三题了 - 这道题理解起来不难 但具体实现 如果对于我这种一次回溯也没有自己独立完成的小白而言 还是很吃力的
- 这道题的思路 我分析一下 主要是三部分分:
- 指定移动规则 给张图吧! 笨办法
- 很好说了 就是 helper 回溯的编写了 这回自己好好学习了一下 感受很深刻啊!
- 最后提供 羊佬 的代码 在移动规则制定上 非常的精简巧妙!
方法(一)
class Solution:
def ballGame(self, num: int, p: List[str]) -> List[List[int]]:
m,n = len(p),len(p[0])
# 回溯 没想清楚 单纯使用循环是不可行的!!!
def nex(dir:int,i:int,j: int)->List[int]:
if i<m and j<n:
if p[i][j] == '.':
if dir == 0: i -= 1
elif dir == 1: i += 1
elif dir == 2: j -= 1
elif dir == 3: j += 1
elif p[i][j] == 'W':
if dir == 0: dir,j = 2,j-1
elif dir == 1: dir,j = 3,j+1
elif dir == 2: dir,i = 1,i+1
elif dir == 3: dir,i = 0,i-1
elif p[i][j] == 'E':
if dir == 0: dir,j = 3,j+1
elif dir == 1: dir,j = 2,j-1
elif dir == 2: dir,i = 0,i-1
elif dir == 3: dir,i = 1,i+1
return [dir,i,j]
@cache
# 这里的编码一定要记住了 需要 利用自身回溯来解决问题!!!
def helper(dir:int,i: int,j:int,k:int):
if k>=0 and 0<=i<m and 0<=j<n:
if p[i][j] == 'O':
return True
else:
dir,i,j = nex(dir,i,j)
return helper(dir,i,j,k-1)
return False
ans = []
for j in range(1,n-1):
if p[0][j]=='.' and helper(1,0,j,num):
ans.append([0,j])
if p[m-1][j]=='.' and helper(0,m-1,j,num):
ans.append([m-1,j])
for i in range(1,m-1):
if p[i][0]=='.' and helper(3,i,0,num):
ans.append([i,0])
if p[i][n-1]=='.' and helper(2,i,n-1,num):
ans.append([i,n-1])
return ans
方法(二)
class Solution:
def ballGame(self, num: int, p: List[str]) -> List[List[int]]:
m,n = len(p),len(p[0])
dir = [[0,1],[1,0],[0,-1],[-1,0]]
def helper(i:int,j:int,d:int):
if p[i][j] == 'O': return 0
if p[i][j] == 'W': d = (d-1)%4
elif p[i][j] == 'E': d = (d+1)%4
i,j = i+dir[d][0],j+dir[d][1]
if 0<=i<m and 0<=j<n:
return helper(i,j,d)+1
return inf
ans = []
for j in range(1,n-1):
if p[0][j]=='.' and helper(0,j,1)<=num:
ans.append([0,j])
if p[m-1][j]=='.' and helper(m-1,j,3)<=num:
ans.append([m-1,j])
for i in range(1,m-1):
if p[i][0]=='.' and helper(i,0,0)<=num:
ans.append([i,0])
if p[i][n-1]=='.' and helper(i,n-1,2)<=num:
ans.append([i,n-1])
return ans
总结
努力、奋斗,多说无益,还要做这周的周赛,小累~