记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
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