LeetCode 每日一题 2021/7/19-2021/7/25

本文介绍了多个算法问题的解决方案,包括查找最高频元素的频数、最小化数组中最大数对和、寻找两个链表的第一个公共节点、复制带随机指针的链表、检查整数范围覆盖、替换隐藏数字得到最晚时间以及从相邻元素对还原数组。通过排序、双指针、复制节点等技巧,展示了如何高效地解决这些复杂问题。
摘要由CSDN通过智能技术生成

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




7/19 1838. Frequency of the Most Frequent Element 最高频元素的频数

排序 次数最多的数必定是已有的数
l坐标为起始点 r为终点坐标
curr记录从[l,r]之间的点都变为nums[r]需要的k值
如果 r右移一位
此时增加的总数是nums[r-1]变到nums[r]需要的数 乘以个数
如果curr大于k 则将左边界往右移 减去差值nums[r]-nums[l]

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

7/20 1877. Minimize Maximum Pair Sum in Array 数组中最大数对和的最小值

从小到大排序 小的和大的组合成数对 可以使最大和最小

def minPairSum(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    n = len(nums)
    nums.sort()
    ans = float('-inf')
    for i in range(n//2):
        ans = max(ans,nums[i]+nums[n-1-i])
    return ans

7/21 剑指 Offer 52. 两个链表的第一个公共节点

双指针 pA pB
某一个到结尾后 指到另一个链表头开始

def getIntersectionNode(headA, headB):
    """
    :type head1, head1: ListNode
    :rtype: ListNode
    """
    pA=headA
    pB=headB
    while pA!=pB:
        pA=headB if not pA else pA.next
        pB=headA if not pB else pB.next
    return pA

7/22 138. Copy List with Random Pointer 复制带随机指针的链表

1.给每个节点后边添加一个备份节点
A->B->C => A->A’->B->B’->C->C’
2.将random指向 复制给备份节点 若A~>C 则A’~>C’
3.处理next指针 使得A->B A’->B’

class Node:
    def __init__(self, x, next=None, random=None):
        self.val = int(x)
        self.next = next
        self.random = random

def copyRandomList(head):
    """
    :type head: Node
    :rtype: Node
    """
    if not head:
        return head
    
    node = head
    while node:
        new_node = Node(node.val,None,None)
        new_node.next = node.next
        node.next = new_node
        node = new_node.next
    
    node = head
    while node:
        if not node.random:
            node.next.random = node.random
        else:
            node.next.random = node.random.next
        node = node.next.next
    
    ans = head.next
    node = head
    while node:
        nt = node.next
        if not nt:
            node.next = nt
        else:
            node.next = nt.next
        node = nt
    return ans

7/23 1893. Check if All the Integers in a Range Are Covered 检查是否区域内所有整数都被覆盖

1.将range先排序 判断left,right与当前l,r的关系
如果left在l左边 因为此时的l是最小的 所以无法达到left 返回False
如果left,right在l,r内 则满足条件
如果left在l,r内 right在r右侧 则将left移动到r+1 继续判断剩余
2.差分数组
diff[i] 记录位置i与前一个位置的差值
如果[l,r]被覆盖 那么diff[l]+=1 diff[r+1]-=1
diff的前缀和 及每个位置被覆盖的次数

def isCovered(ranges, left, right):
    """
    :type ranges: List[List[int]]
    :type left: int
    :type right: int
    :rtype: bool
    """
    ranges.sort(key=lambda x:(x[0],x[1]))
    
    for l,r in ranges:
        if left<l:
            return False
        elif l<=left and right<=r:
            return True
        elif l<=left and right>r:
            left = r+1
    return False

def isCovered2(ranges, left, right):
    """
    :type ranges: List[List[int]]
    :type left: int
    :type right: int
    :rtype: bool
    """
    diff = [0]*52
    for l,r in ranges:
        diff[l] +=1
        diff[r+1] -= 1
    suff = []
    curr = 0
    for i in diff:
        curr += i 
        suff.append(curr)
    
    for i in range(left,right+1):
        if suff[i]==0:
            return False
    return True

7/24 1736. Latest Time by Replacing Hidden Digits 替换隐藏数字得到的最晚时间

一次考虑 小时 分钟
小时:
如果两个? 为23
如果前一个为?
后一小于等于3 前一个为2
否则 前一个为1
如果后一个为?
如果前一个为2 后一个为3
否则 后一个为9
分钟
如果两个? 为59
如果前一个为? 前一个为5
如果后一个为? 后一个为9

def maximumTime(time):
    """
    :type time: str
    :rtype: str
    """
    l = list(time)
    loc = 0
    
    if l[loc]=="?":
        if l[loc+1]=="?":
            l[loc]="2"
            l[loc+1]="3"
        else:
            if l[loc+1]<="3":
                l[loc] = "2"
            else:
                l[loc] = "1"
    else:
        if l[loc+1]=="?":
            if l[loc]=="2":
                l[loc+1] = "3"
            else:
                l[loc+1] = "9"
    
    loc = 3
    if l[loc]=="?":
        if l[loc+1]=="?":
            l[loc]="5"
            l[loc+1]="9"
        else:
            l[loc] = "5"
    else:
        if l[loc+1]=="?":
            l[loc+1] = "9"
            
    return "".join(l)

7/25 1743. Restore the Array From Adjacent Pairs 从相邻元素对还原数组

中间的元素相邻元素必定有两个 首位元素相邻元素只有一个
找到相邻元素只有一个的元素 放置首部 依次考虑后续

def restoreArray(adjacentPairs):
    """
    :type adjacentPairs: List[List[int]]
    :rtype: List[int]
    """
    from collections import defaultdict
    m = defaultdict(list)
    if len(adjacentPairs)==1:
        return adjacentPairs[0]
    head = set()
    for i,j in adjacentPairs:
        m[i].append(j)
        m[j].append(i)
        if i in head:
            head.remove(i)
        else:
            head.add(i)
        if j in head:
            head.remove(j)
        else:
            head.add(j)
            
    ans = [0]*(len(adjacentPairs)+1)
    
    first= head.pop()
    pre = float('inf')
    curr = first
    ans[0] = first
    loc = 1
    while loc<=len(adjacentPairs): 
        l = m[curr]
        for i in l:
            if i == pre:
                continue
            ans[loc] = i
            pre = curr
            curr = i
            break
        loc +=1
    return ans

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值