记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
- 8/23 1646. Get Maximum in Generated Array 获取生成数组中的最大值
- 8/24 787. Cheapest Flights Within K Stops K 站中转内最便宜的航班
- 8/25 797. All Paths From Source to Target 所有可能的路径
- 8/26 881. Boats to Save People 救生艇
- 8/27 295. Find Median from Data Stream 数据流的中位数
- 8/28 1480. Running Sum of 1d Array 一维数组的动态和
- 8/29 1588. Sum of All Odd Length Subarrays 所有奇数长度子数组的和
8/23 1646. Get Maximum in Generated Array 获取生成数组中的最大值
模拟 注意2*i+1不能超过n
def getMaximumGenerated(n):
"""
:type n: int
:rtype: int
"""
nums = {}
nums[0]=0
nums[1]=1
if n==0:
return 0
ans = 1
for i in range(1,n//2+1):
nums[2*i]=nums[i]
ans = max(ans,nums[i])
if 2*i+1>n:
break
nums[2*i+1] = nums[i]+nums[i+1]
ans = max(ans,nums[i]+nums[i+1])
return ans
8/24 787. Cheapest Flights Within K Stops K 站中转内最便宜的航班
1.dp
m[t][loc] 记录第t次转机 到达loc最少消耗
对于航班(s,d,v) m[t][d] = min(m[t][d],m[t-1][s]+v)
2.dijskra
dic 记录起点s能够到达的d以及价格v
query 记录起点s以及已经消耗的价格
因为起点s的价格可能会在当前一轮改变 所以要记录之前的价格
visited记录当前达到过的地方最小消耗
def findCheapestPrice(n, flights, src, dst, k):
"""
:type n: int
:type flights: List[List[int]]
:type src: int
:type dst: int
:type k: int
:rtype: int
"""
m = [[float('inf')]*n for _ in range(k+2)]
m[0][src] = 0
for t in range(1,k+2):
for s,d,v in flights:
m[t][d] = min(m[t][d],m[t-1][s]+v)
ans = min(m[t][dst] for t in range(1,k+2))
return -1 if ans==float('inf') else ans
def findCheapestPrice2(n, flights, src, dst, k):
"""
:type n: int
:type flights: List[List[int]]
:type src: int
:type dst: int
:type k: int
:rtype: int
"""
from collections import defaultdict
dic = defaultdict(list)
for s,d,v in flights:
dic[s].append((d,v))
query = [(src,0)]
visited = [float('inf')]*n
visited[src]=0
ans = float('inf')
while k>=0:
k-=1
tmpq = []
for s,value in query:
for d,price in dic[s]:
if value+price<visited[d]:
tmpq.append((d,value+price))
visited[d] = value+price
if d==dst:
ans = min(ans,value+price)
query = tmpq[:]
return -1 if ans==float('inf') else ans
8/25 797. All Paths From Source to Target 所有可能的路径
BFS 广搜 无环图
cur记录当前走过的路径 loc为当前点
当loc为目标点时 记录当前路径
def allPathsSourceTarget(graph):
"""
:type graph: List[List[int]]
:rtype: List[List[int]]
"""
n = len(graph)
ans = []
def bfs(cur,loc):
cur.append(loc)
if loc==n-1:
ans.append(cur)
return
for nt in graph[loc]:
bfs(cur[:],nt)
bfs([],0)
return ans
8/26 881. Boats to Save People 救生艇
1.从大到小排序
如果等于limit 则救生艇+1
否则留下一搜能够容纳limit-p的救生艇可供后续使用
超时
2.双指针
排序后 最大和最小合乘 如果可以则坐船 否则只能坐最大的一个
def numRescueBoats(people, limit):
"""
:type people: List[int]
:type limit: int
:rtype: int
"""
people.sort(reverse=True)
leave = []
ans = 0
for p in people:
if p==limit:
ans +=1
continue
if len(leave)>0:
space = leave[0]
if space>=p:
leave.pop(0)
continue
ans += 1
leave = [limit-p]+leave
return ans
def numRescueBoats2(people, limit):
"""
:type people: List[int]
:type limit: int
:rtype: int
"""
people.sort(reverse=True)
n = len(people)
l,r=0,n-1
ans = 0
while l<=r:
ans +=1
if people[l]+people[r]<=limit:
r-=1
l+=1
return ans
8/27 295. Find Median from Data Stream 数据流的中位数
1.自己实现heap
维护两个堆 一个小顶堆 一个大顶堆
左边堆left为大顶堆保存小数
右边堆right为小顶堆保存大数 优先放进right
left right个数差不大于1
2.使用heapq
只提供了小顶堆
将num去负数-num存入小顶堆 实现大顶堆效果 所有数压入取出需要取反
class MedianFinder1(object):
def __init__(self):
"""
initialize your data structure here.
"""
self.left=[0]
self.right=[0]
self.leftnum=0
self.rightnum=0
def addNum(self, num):
"""
:type num: int
:rtype: None
"""
#往小顶堆末尾增加数据 将其up
def minheapup(loc):
while loc>1:
if self.right[loc//2]>self.right[loc]:
self.right[loc//2],self.right[loc] = self.right[loc],self.right[loc//2]
loc = loc//2
else:
return
#往大顶堆末尾增加数据 将其up
def maxheapup(loc):
while loc>1:
if self.left[loc//2]<self.left[loc]:
self.left[loc//2],self.left[loc] = self.left[loc],self.left[loc//2]
loc = loc//2
else:
return
#替换了小顶堆的堆顶数据 将堆顶数据down
def minheapdown():
loc =1
while loc<self.rightnum:
l,r=loc*2,loc*2+1
minv=self.right[loc]
if l>self.rightnum:
return
elif r>self.rightnum:
minv=self.right[l]
else:
minv=min(self.right[l],self.right[r])
if minv>=self.right[loc]:
return
else:
if r>self.rightnum:
self.right[l],self.right[loc]=self.right[loc],self.right[l]
loc = l
elif self.right[l]<self.right[r]:
self.right[l],self.right[loc]=self.right[loc],self.right[l]
loc = l
else:
self.right[r],self.right[loc]=self.right[loc],self.right[r]
loc = r
#替换了大顶堆的堆顶数据 将堆顶数据down
def maxheapdown():
loc =1
while loc<self.leftnum:
l,r=loc*2,loc*2+1
maxv=self.left[loc]
if l>self.leftnum:
return
elif r>self.leftnum:
maxv=self.left[l]
else:
maxv=max(self.left[l],self.left[r])
if maxv<=self.left[loc]:
return
else:
if r>self.leftnum:
self.left[l],self.left[loc]=self.left[loc],self.left[l]
loc = l
elif self.left[l]<self.left[r]:
self.left[r],self.left[loc]=self.left[loc],self.left[r]
loc = r
else:
self.left[l],self.left[loc]=self.left[loc],self.left[l]
loc = l
if self.leftnum==self.rightnum:
if self.leftnum>0 and self.left[1]>num:
self.left[1],num=num,self.left[1]
maxheapdown()
self.right.append(num)
self.rightnum+=1
minheapup(self.rightnum)
elif num>self.right[1]:
#将小顶堆 值替换成num 放入大顶堆
self.right[1],num = num,self.right[1]
#整理小顶堆
minheapdown()
##整理大顶堆
self.left.append(num)
self.leftnum+=1
maxheapup(self.leftnum)
else:
self.left.append(num)
self.leftnum+=1
maxheapup(self.leftnum)
print(self.left,self.right)
def findMedian(self):
"""
:rtype: float
"""
if self.leftnum==self.rightnum:
return float(self.left[1]+self.right[1])/2.0
else:
return self.right[1]
from heapq import *
class MedianFinder(object):
def __init__(self):
"""
initialize your data structure here.
"""
self.A=[] #大顶堆 保存较小的一半 存 -num
self.B=[] #小顶堆 存较大的一半
def addNum(self, num):
"""
:type num: int
:rtype: None
"""
if len(self.A)!=len(self.B):
heappush(self.A,-heappushpop(self.B,num))
else:
heappush(self.B,-heappushpop(self.A,-num))
def findMedian(self):
"""
:rtype: float
"""
return self.B[0] if len(self.A) != len(self.B) else (self.B[0] - self.A[0]) / 2.0
8/28 1480. Running Sum of 1d Array 一维数组的动态和
在原数组基础上 当前位置值=当前位置+之前位置
def runningSum(nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
for i in range(1,len(nums)):
nums[i] += nums[i-1]
return nums
8/29 1588. Sum of All Odd Length Subarrays 所有奇数长度子数组的和
可以考虑每一位数出现在子数组中的次数
当在位置i时 前面有left个数 后面有right个数
需要组成奇数长度的子数组 那么在left中取的个数加上right中取的个数需要为偶数 加上自己1个变为奇数
可以考虑 left,right中取奇数个odd的可能性 取偶数个even的可能性 分别相乘
即为当前位置能够出现在奇数长度子数组中的次数
def sumOddLengthSubarrays(arr):
"""
:type arr: List[int]
:rtype: int
"""
n = len(arr)
ans = 0
for i in range(n):
left = i
right = n-1-i
lefteven = left//2+1
leftodd = (left+1)//2
righteven = right//2+1
rightodd = (right+1)//2
ans +=(lefteven*righteven+leftodd*rightodd)*arr[i]
return ans