记录 22.9.24 LCP竞赛1~3

记录 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
解释:如下表所示, 第 24 天两地气温变化趋势相同,且持续时间最长,因此返回 4-2=2

提示:

  • 2 <= temperatureA.length == temperatureB.length <= 1000
  • -20 <= temperatureA[i], temperatureB[i] <= 40

解题思路: 这道题 刚看到的时候有些懵,不过按照题意一步一步处理即可! 读懂题意是关键所在:

  1. 对两个数组进行 上升、平稳、下降 三个程度的判断,可以分别用 1,0,-1 来表示;
  2. 得到数组后 使用 双指针进行连续区域 的判断即可
  • 此题不难,本次做题后最深的感受就是一定要快速地摸清楚作者想说什么,然后下手就可以快一些,实现起来并不难,一定要有信心!
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] 不相等

解题思路: 这是道 题 不过在此没有用图的知识,思考了很久,主要思路就是:

  1. 确定可以进行判断的点,即 该点仅作为接受点不进行发射,即 该点仅位于path[][1]的位置,未在path[][0]的位置出现;
  2. 统计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) 好遗憾啊! 这次竞赛也就停步于第三题了
  • 这道题理解起来不难 但具体实现 如果对于我这种一次回溯也没有自己独立完成的小白而言 还是很吃力的
  • 这道题的思路 我分析一下 主要是三部分分:
  1. 指定移动规则 给张图吧! 笨办法
    在这里插入图片描述
  2. 很好说了 就是 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          

总结

  努力、奋斗,多说无益,还要做这周的周赛,小累~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值