LeetCode 每日一题 2021/8/23-2021/8/29

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




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


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值