LeetCode 5768. 最小侧跳次数(贪心)

题目

思路

阅读完题干后可以发现需要侧跳的时机是下一个点有障碍,且障碍处在青蛙当前所在跑道。在做周赛时我是先考虑了特殊情况,即当前青蛙所在点的另外的跑道也有障碍,这种情况下青蛙只有唯一的侧跳选择(因为有两条跑道都被封住了)。而如果青蛙所在点所有跑道都没有障碍,那青蛙当前就有两条跑道可以选择。这时可以用贪心的想法,对于待选的两条跑道,分别查找它们下一个最近障碍所在地点,然后选择其中较大者,即保证青蛙在尽量大的距离内不做侧跳调整。在查找下一个最近障碍所在地点时,我是先保存每个跑道障碍出现的地点,然后在出现上述情况以当前位置为起点,二分查找最近障碍点。如果未找到该点,说明后面都是通畅的,这里我是用正无穷表示的(其实这里可以直接返回了,但是竞赛的时候没考虑到这一点)。这里我是遍历数组解决的,时间复杂度为O(n\log(n))。

代码

class Solution:
    def minSideJumps(self, obstacles: List[int]) -> int:
        n=len(obstacles)
        s=2
        ans=0
        q1=[]
        q2=[]
        q3=[]
        for i in range(n):
            if obstacles[i]==1:
                q1.append(i)
            elif obstacles[i]==2:
                q2.append(i)
            elif obstacles[i]==3:
                q3.append(i)
        #print(q1,q2,q3)
        def search(s,flag):
            nonlocal q1,q2,q3
            l=0
            if flag==1:
                if not q1:
                    return float('inf')
                r=len(q1)-1
                res=r
                while l<=r:
                    mid=(l+r)>>1
                    if q1[mid]<=s:
                        l=mid+1
                    else:
                        res=mid
                        r=mid-1
                #print('res',res)
                #print()
                # if res>=len(q1):
                #     return float('inf')
                if q1[res]<=s:      #这种情况即数组中所有障碍都在起始点之前,表示后面通畅,可以用正无穷表示这种情况
                    return float('inf')
                else:
                    return q1[res]
            elif flag==2:
                if not q2:
                    return float('inf')
                r=len(q2)-1
                res=r
                while l<=r:
                    mid=(l+r)>>1
                    if q2[mid]<=s:
                        l=mid+1
                    else:
                        res=mid
                        r=mid-1
                if q2[res]<=s:
                    return float('inf')
                else:
                    return q2[res]
            else:
                if not q3:
                    return float('inf')
                r=len(q3)-1
                res=r
                while l<=r:
                    mid=(l+r)>>1
                    if q3[mid]<=s:
                        l=mid+1
                    else:
                        res=mid
                        r=mid-1
                if q3[res]<=s:
                    return float('inf')
                else:
                    return q3[res]
                
                
        for i in range(n-1):
            #print(i,s,ans)
            if obstacles[i+1]==s:
                if obstacles[i]==1:
                    if s==2:
                        s=3
                    else:
                        s=2
                elif obstacles[i]==2:
                    if s==1:
                        s=3
                    else:
                        s=1
                elif obstacles[i]==3:
                    if s==2:
                        s=1
                    else:
                        s=2
                else:
                    if s==1:
                        temp1=search(i+1,2)
                        temp2=search(i+1,3)
                        if temp1<temp2:
                            s=3
                        else:
                            s=2
                    elif s==2:
                        temp1=search(i+1,1)
                        temp3=search(i+1,3)
                        #print(temp1,temp3)
                        if temp1<temp3:
                            s=3
                        else:
                            s=1
                    elif s==3:
                        temp1=search(i+1,1)
                        temp2=search(i+1,2)
                        if temp1<temp2:
                            s=2
                        else:
                            s=1
                ans+=1
        return ans

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值