LeetCode 每日一题 2026/1/1-2026/1/7
记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
-
-
- [5/11 2553. 分割数组中数字的数位](#5/11 2553. 分割数组中数字的数位)
- [5/12 1665. 完成所有任务的最少初始能量](#5/12 1665. 完成所有任务的最少初始能量)
- [5/13 1674. 使数组互补的最少操作次数](#5/13 1674. 使数组互补的最少操作次数)
- [5/14 2784. 检查数组是否是好的](#5/14 2784. 检查数组是否是好的)
- [5/15 153. 寻找旋转排序数组中的最小值](#5/15 153. 寻找旋转排序数组中的最小值)
- [5/16 154. 寻找旋转排序数组中的最小值 II](#5/16 154. 寻找旋转排序数组中的最小值 II)
- 5/17
-
5/11 2553. 分割数组中数字的数位
对每个数依次操作
python
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 即最少初始能量。
python
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 次)
最后对差分前缀和扫描一遍,取最小值即答案。
python
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两次
python
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. 寻找旋转排序数组中的最小值
- 按序遍历
- 二分
python
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点比较得到最小的点 因为有可能是个顺序序列
python
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
python