[英雄星球六月集训LeetCode解题日报] 0601 数组
一、 327. 所有奇数长度子数组的和
1. 题目描述
给你一个正整数数组 arr ,请你计算所有可能的奇数长度子数组的和。
子数组 定义为原数组中的一个连续子序列。
请你返回 arr 中 所有奇数长度子数组的和
2. 思路分析
求数组中所有奇数长度子数组的和的和。
分析每个元素在几个奇数长度子数组里,乘一下,加起来就行。
a[i] 如果在奇数长度子数组里,那么它左右两边的数字个数和一定是偶数,左右同为奇或偶,分别分析即可。
a[i]在原数组中左边有l=i个数,右边有r=n-i-1个数:
奇数个数: 左边(l+1)//2,右边(r+1)//2
偶数个数: 左边 l//2+1, 右边r//2+1
最坏时间复杂度O(n)
40 ms Python3 89.19%
3. 代码实现
class Solution:
def sumOddLengthSubarrays(self, arr: List[int]) -> int:
n = len(arr)
s = 0
for i in range(n):
l,r =i ,n-i-1
l1,r1 = (l+1)//2,(r+1)//2
l2,r2 = l//2+1,r//2+1
s += arr[i] * (l1*r1 + l2*r2)
return s
二、 1848. 到目标元素的最小距离
链接: 1848. 到目标元素的最小距离
1. 题目描述
给你一个整数数组 nums (下标 从 0 开始 计数)以及两个整数 target 和 start ,请你找出一个下标 i ,满足 nums[i] == target 且 abs(i - start) 最小化 。注意:abs(x) 表示 x 的绝对值。
返回 abs(i - start) 。
题目数据保证 target 存在于 nums 中。
2. 思路分析
从数组中找指定的数距离pos下标最近的下标。
遍历
最坏时间复杂度O(n)
40 ms Python3 55.06%
3. 代码实现
class Solution:
def getMinDistance(self, nums: List[int], target: int, start: int) -> int:
d = len(nums) + 1
for i,n in enumerate(nums):
if nums[i] == target:
d = min(d,abs(i-start))
return d
三、 1652. 拆炸弹
链接: 1652. 拆炸弹
1. 题目描述
你有一个炸弹需要拆除,时间紧迫!你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。
为了获得正确的密码,你需要替换掉每一个数字。所有数字会 同时 被替换。
如果 k > 0 ,将第 i 个数字用 接下来 k 个数字之和替换。
如果 k < 0 ,将第 i 个数字用 之前 k 个数字之和替换。
如果 k == 0 ,将第 i 个数字用 0 替换。
由于 code 是循环的, code[n-1] 下一个元素是 code[0] ,且 code[0] 前一个元素是 code[n-1] 。
给你 循环 数组 code 和整数密钥 k ,请你返回解密后的结果来拆除炸弹
2. 思路分析
按照题目规则处理每个数,把当前数替换为旁边k个数的和。
由于可能向前走,且|k|<n,为了方便处理直接把原数组乘3,处理中间那段就不用管下标问题了。
区间和就算个前缀和。
最坏时间复杂度O(n)
32 ms, Python3 96.76%
3. 代码实现
class Solution:
def decrypt(self, code: List[int], k: int) -> List[int]:
n = len(code)
new = code[:]*3
pre = list(accumulate(new,initial=0)) # 前缀数组,sum[i,j] = pre[j+1]-pre[i]
for i in range(n):
new_i = i + n
if k == 0:
code[i] = 0
elif k > 0:
code[i] = pre[new_i+1+k] - pre[new_i+1]
else:
code[i] = pre[new_i] - pre[new_i+k]
return code
四、 1640. 能否连接形成数组
链接: 1640. 能否连接形成数组
1. 题目描述
给你一个整数数组 arr ,数组中的每个整数 互不相同 。另有一个由整数数组构成的数组 pieces,其中的整数也 互不相同 。请你以 任意顺序 连接 pieces 中的数组以形成 arr 。但是,不允许 对每个数组 pieces[i] 中的整数重新排序。
如果可以连接 pieces 中的数组形成 arr ,返回 true ;否则,返回 false 。
2. 思路分析
判断piece中所有切片拼起来是不是arr。
字典储存arr下标,遍历每个piece从字典里找第一个字符位置,然后从位置匹配
最坏时间复杂度O(n)
36 ms Python3 75.21%
3. 代码实现
class Solution:
def canFormArray(self, arr: List[int], pieces: List[List[int]]) -> bool:
s = {v:k for k,v in enumerate(arr)}
n = len(arr)
for piece in pieces:
i = s.get(piece[0])
if i is None:
return False
for c in piece :
if i == n or arr[i] != c:
return False
i += 1
return True