LeetCode 每日一题 2021/8/2-2021/8/8

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步




8/2 743. Network Delay Time 网络延迟时间

dfs 记录每一个col下的(row,v)
对col从小到大考虑 每一个col的list tmp
在tmp中根据row,v排序 得到需要的v序列

class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
    
def verticalTraversal(root):
    """
    :type root: TreeNode
    :rtype: List[List[int]]
    """
    from collections import defaultdict
    global dic
    dic = defaultdict(list)
    def find(node,row,col):
        global dic
        if not node:
            return
        dic[col].append((row,node.val))
        find(node.left,row+1,col-1)
        find(node.right,row+1,col+1)
    find(root,0,0)
    
    l = dic.keys()
    l.sort()
    ans = []
    for i in l:
        tmp = dic[i]
        tmp.sort(key=lambda x:(x[0],x[1]))
        t = [x[1] for x in tmp]
        ans.append(t)
    return ans

8/3 581. Shortest Unsorted Continuous Subarray 最短无序连续子数组

从左到右找最右边小于左侧最大值的位置
从右到左找最左边大于右侧最小值的位置

def findUnsortedSubarray(nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        if n==1:
            return 0
        
        maxn = float('-inf')
        right = -1
        
        for i in range(n):
            if maxn>nums[i]:
                right = i
            else:
                maxn = nums[i]
        if right == -1:
            return 0
        minn =float('inf')
        left = -1
        for i in range(n-1,-1,-1):
            if minn<nums[i]:
                left = i
            else:
                minn = nums[i]
        return right-left+1

8/4 611. Valid Triangle Number

1.排序找前两条边 二分找第三条边
2.排序
确定最大边nums[i] 剩下左右边位置为l,r=0,i-1
如果nums[l]+nums[r]>nums[i]
那么nums[x]+nums[r]必定大于nums[i] (r>x>l)
可以得到r-l个结果 之后将r往左移
否则和不够 将l往右移

def triangleNumber(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    nums.sort()
    n = len(nums)
    def find(v,li):
        l,r = 0,len(li)-1
        while l<=r:
            mid = (l+r)>>1
            if li[mid]<v:
                l = mid+1
            else:
                r = mid-1
        return l
    ans = 0
    for i in range(n-2):
        for j in range(i+1,n-1):
            s = nums[i]+nums[j]            
            x = j+1
            if s<=nums[x]:
                continue
            ans += find(s,nums[x:])
    return ans

def triangleNumber2(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    nums.sort()
    n = len(nums)
    ans = 0
    for i in range(n-1,1,-1):
        l,r = 0,i-1
        while l<r:
            if nums[l]+nums[r]>nums[i]:
                ans += r-l
                r-=1
            else:
                l+=1
    return ans

8/5 802. Find Eventual Safe States 找到最终的安全状态

没有出的点为安全起点
记录每个点的入点有哪些 考虑出度次数
没考虑一个点 将其所有入度点的出度次数减一 如果为零则加入考虑队列

def eventualSafeNodes(graph):
    """
    :type graph: List[List[int]]
    :rtype: List[int]
    """
    n = len(graph)
    rg = [[] for _ in range(n)]
    for i,tmp in enumerate(graph):
        for x in tmp:
            rg[x].append(i)
    nextlen = [len(x) for x in graph]
    
    l = [i for i,num in enumerate(nextlen) if num==0]
    while l:
        loc = l.pop(0)
        for i in rg[loc]:
            nextlen[i]-=1
            if nextlen[i]==0:
                l.append(i)
    return [i for i,num in enumerate(nextlen) if num==0]

8/6 847. Shortest Path Visiting All Nodes 访问所有节点的最短路径

使用n位的二进制记录途径的点
使用BFS q初始化为第一步的n个点 点i,路线状态path,步数dist
mem初始化为已经走过的状况 点i,路线状态path
考虑某个点point 遍历他能够连通的node
将node加入到path中 如果(node,path_add)没有考虑过
则将状态加入到待考虑队列q中
如果path的状态全为1 及所有点都经过了 此时返回dist 因为BFS必定dist最小

def shortestPathLength(graph):
    """
    :type graph: List[List[int]]
    :rtype: int
    """
    n = len(graph)
    q = [(i,1<<i,0) for i in range(n)]
    mem = {(i,1<<i) for i in range(n)}
    ans = 0
    
    while q:
        point,path,dist = q.pop(0)
        if path == (1<<n)-1:
            ans = dist
            break
        for node in graph[point]:
            path_add = path | (1<<node)
            if (node,path_add) not in mem:
                q.append((node,path_add,dist+1))
                mem.add((node,path_add))
    return ans

8/7 457. Circular Array Loop 环形数组是否存在循环

从头开始遍历 mem记录失败的位置
如果过loc已经在mem中 直接跳过
pre记录之前位置 net记录当前位置
如果net>=n 或者<0 修正回队列位置
如果pre,net两数正负不一 则返回
s记录当前已经走过的位置
如果当前net已经走过
如果net和pre相同 说明只有1个位置不满足条件 退出
如果net和pre不同 说明构成了循环 返回True
退出 说明s中位置都不能构成循环 记录到mem中

def circularArrayLoop(nums):
    """
    :type nums: List[int]
    :rtype: bool
    """
    n = len(nums)
    mem = set()
    for loc in range(n):
        if loc in mem:
            continue
        pre = loc
        s = set()
        s.add(pre)
        while True:
            net = pre + nums[pre]
            while net<0:
                net+= n
            while net>=n:
                net-=n
            if nums[pre] *nums[net]<0:
                break
            if net in s:
                if net==pre:
                    break
                else:
                    return True
            s.add(net)
            pre = net
        mem = mem.union(s)
    return False

8/8 1137. N-th Tribonacci Number 第 N 个泰波那契数

记录前三个数 得到第四个数
更新三个数 位置后移一位

def tribonacci(n):
    """
    :type n: int
    :rtype: int
    """
    if n==0:
        return 0
    if n<3:
        return 1
    t0,t1,t2 = 0,1,1
    for i in range(3,n+1):
        t3 = t0+t1+t2
        t0,t1,t2 = t1,t2,t3
    return t2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值