LeetCode 每日一题 2026/5/11-2026/5/17

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




5/11 2553. 分割数组中数字的数位

对每个数依次操作

def separateDigits(nums):
    """
    :type nums: List[int]
    :rtype: List[int]
    """
    def func(num):
        ans = []
        while num>0:
            ans.append(num%10)
            num//=10
        return ans[::-1]
    ans=[]
    for num in nums:
        ans.extend(func(num))
    return ans



5/12 1665. 完成所有任务的最少初始能量

每个任务为 [actual, minimum],表示做任务前至少要有 minimum 点能量,做完会消耗 actual 点。
关键在于任务顺序:
若先做“门槛高但消耗低”的任务,可以尽早满足高门槛,减少后续临时补能量。
将任务按 (minimum - actual) 从大到小排序,可使总初始能量最小。
排序后线性遍历,维护:
cur: 当前能量 ans: 需要的最少初始能量
对每个任务 [a, m]:
若 cur < m,说明当前能量不足以开始该任务,需要补充 (m - cur) 到 ans,并令 cur = m
完成任务后 cur -= a
最终 ans 即最少初始能量。

def minimumEffort(tasks):
    """
    :type tasks: List[List[int]]
    :rtype: int
    """
    tasks.sort(key=lambda x: x[1] - x[0], reverse=True)

    ans = 0
    cur = 0

    for a, m in tasks:
        if cur < m:
            ans += m - cur
            cur = m
        cur -= a

    return ans



5/13 1674. 使数组互补的最少操作次数

把数组按对称位置配对:(nums[i], nums[n-1-i])。
目标是让每一对的和都变成同一个值 x(2 <= x <= 2 * limit)。
对某一对 (a, b),设 lo = min(a, b),hi = max(a, b),s = a + b。
则把该对变成和为 x 的最少操作数有三档:
0 次:x == s
1 次:x 在 [lo + 1, hi + limit](改动其中一个数即可)
2 次:其余情况
因此可把“所有可能的 x 的总操作数”看成一条长度为 [2…2limit] 的代价曲线,
每一对都会对这条曲线做区间加减。使用差分数组可在 O(1) 更新每对贡献:
先给全区间 [2, 2
limit] 加 2
给区间 [lo+1, hi+limit] 减 1(从 2 次降到 1 次)
给点 s 再减 1(从 1 次降到 0 次)
最后对差分前缀和扫描一遍,取最小值即答案。

def minMoves(nums, limit):
    """
    :type nums: List[int]
    :type limit: int
    :rtype: int
    """
    n = len(nums)
    max_sum = 2 * limit
    diff = [0] * (max_sum + 2)

    for i in range(n // 2):
        a = nums[i]
        b = nums[n - 1 - i]
        lo = min(a, b)
        hi = max(a, b)
        s = a + b

        # 全部目标和先按 2 次操作计入
        diff[2] += 2
        diff[max_sum + 1] -= 2

        # 一次操作可达区间
        diff[lo + 1] -= 1
        diff[hi + limit + 1] += 1

        # 恰好等于当前和时,0 次操作
        diff[s] -= 1
        diff[s + 1] += 1

    ans = float("inf")
    cur = 0
    for x in range(2, max_sum + 1):
        cur += diff[x]
        if cur < ans:
            ans = cur

    return ans




5/14 2784. 检查数组是否是好的

如果长度为n 那么数组中需要存在1~n-2各一次 n-1两次

def isGood(nums):
    """
    :type nums: List[int]
    :rtype: bool
    """
    n=len(nums)
    ck={x:1 for x in range(1,n-1)}
    ck[n-1]=2
    for num in nums:
        if num in ck:
            ck[num]-=1
            if ck[num]==0:
                del ck[num]
        else:
            return False
    return True





5/15 153. 寻找旋转排序数组中的最小值

  1. 按序遍历
  1. 二分
def findMin(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    n = len(nums)
    if n<2:
        return nums[0]
    if nums[0]<nums[-1]:
        return nums[0]
    
    for i in range(1,n):
        if nums[i]<nums[i-1]:
            return nums[i]

def findMin2(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    low, high = 0, len(nums) - 1
    while low < high:
        pivot = low + (high - low) // 2
        if nums[pivot] < nums[high]:
            high = pivot 
        else:
            low = pivot + 1
    return nums[low]



5/16 154. 寻找旋转排序数组中的最小值 II

寻找反转点
从mid开始
和left判断 如果value比left的要小那么[left,mid]非递增 因为有重复的所以判断left>=mid
同理right 也如此判断
找到反转点mid 此时 与left点比较得到最小的点 因为有可能是个顺序序列

def findMin(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    left = 0
    right =len(nums)-1
    mid =(left+right)//2
    while mid>left and nums[left]>=nums[mid]:
        mid-=1
    while mid<right and nums[right]<=nums[mid]:
        mid+=1
    return min(nums[mid],nums[left])



5/17 1306. 跳跃游戏 III

BFS
记录已经访问过的位置
对于当前位置 如果能够跳跃到位置i 则将位置i加入到队列中
如果位置i是终点 则返回True
如果队列为空 则返回False

def canReach(arr, start):
    """
    :type arr: List[int]
    :type start: int
    :rtype: bool
    """
    from collections import deque
    n = len(arr)
    q = deque([start])
    visited = set([start])
    while q:
        i = q.popleft()
        if arr[i] == 0:
            return True
        if i + arr[i] < n and i + arr[i] not in visited:
            q.append(i + arr[i])
            visited.add(i + arr[i])
        if i - arr[i] >= 0 and i - arr[i] not in visited:
            q.append(i - arr[i])
            visited.add(i - arr[i])
    return False




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值