6451. 找出最大的可达成数字
class Solution:
def theMaximumAchievableX(self, num: int, t: int) -> int:
return num+2*t
6899. 达到末尾下标所需的最大跳跃次数
class Solution:
def maximumJumps(self, nums: List[int], t: int) -> int:
n = len(nums)
f = [-inf]*n
f[0] = 0
for i in range(n-1):
for j in range(i+1,n):
if abs(nums[j]-nums[i]) <= t:
f[j] = max(f[j],f[i]+1)
return f[-1] if f[-1] > -inf else -1
nlgn线段树做法
class ZKW:
# n = 1
# size = 1
# log = 2
# d = [0]
# op = None
# e = 10 ** 15
"""自低向上非递归写法线段树,0_indexed
tmx = ZKW(pre, max, -2 ** 61)
"""
__slots__ = ('n', 'op', 'e', 'log', 'size', 'd')
def __init__(self, V, OP, E):
"""
V: 原数组
OP: 操作:max,min,sum
E: 每个元素默认值
"""
self.n = len(V)
self.op = OP
self.e = E
self.log = (self.n - 1).bit_length()
self.size = 1 << self.log
self.d = [E for i in range(2 * self.size)]
for i in range(self.n):
self.d[self.size + i] = V[i]
for i in range(self.size - 1, 0, -1):
self.update(i)
def set(self, p, x):
# assert 0 <= p and p < self.n
update = self.update
p += self.size
self.d[p] = x
for i in range(1, self.log + 1):
update(p >> i)
def get(self, p):
# assert 0 <= p and p < self.n
return self.d[p + self.size]
def query(self, l, r): # [l,r)左闭右开
# assert 0 <= l and l <= r and r <= self.n
sml, smr, op, d = self.e, self.e, self.op, self.d
l += self.size
r += self.size
while l < r:
if l & 1:
sml = op(sml, d[l])
l += 1
if r & 1:
smr = op(d[r - 1], smr)
r -= 1
l >>= 1
r >>= 1
return self.op(sml, smr)
def all_query(self):
return self.d[1]
def max_right(self, l, f):
"""返回l右侧第一个不满足f的位置"""
# assert 0 <= l and l <= self.n
# assert f(self.e)
if l == self.n:
return self.n
l += self.size
sm, op, d, size = self.e, self.op, self.d, self.size
while True:
while l % 2 == 0:
l >>= 1
if not (f(op(sm, d[l]))):
while l < size:
l = 2 * l
if f(op(sm, d[l])):
sm = op(sm, d[l])
l += 1
return l - size
sm = op(sm, d[l])
l += 1
if (l & -l) == l:
break
return self.n
def min_left(self, r, f):
"""返回r左侧连续满足f的最远位置的位置"""
# assert 0 <= r and r < self.n
# assert f(self.e)
if r == 0:
return 0
r += self.size
sm, op, d, size = self.e, self.op, self.d, self.size
while True:
r -= 1
while r > 1 and (r % 2):
r >>= 1
if not (f(op(d[r], sm))):
while r < size:
r = (2 * r + 1)
if f(op(d[r], sm)):
sm = op(d[r], sm)
r -= 1
return r + 1 - size
sm = op(d[r], sm)
if (r & -r) == r:
break
return 0
def update(self, k):
self.d[k] = self.op(self.d[2 * k], self.d[2 * k + 1])
def __str__(self):
return str([self.get(i) for i in range(self.n)])
class Solution:
def maximumJumps(self, nums: List[int], t: int) -> int:
n = len(nums)
h = set(nums)
for v in nums:
h.add(v-t)
h.add(v+t)
h = sorted(h)
size = len(h)
f = ZKW([-inf]*size,max,-inf)
f.set(bisect_left(h,nums[0]),0)
for i in range(1,n):
l,r = bisect_left(h,nums[i]-t),bisect_right(h,nums[i]+t)
i = bisect_left(h,nums[i])
ans = max(f.get(i), f.query(l,r)+1)
f.set(i,ans)
return [-1,ans][ans>-inf]
6912. 构造最长非递减子数组
class Solution:
def maxNonDecreasingLength(self, nums1, nums2):
n = len(nums1)
x = y = 1
ans = 1
for i in range(1,n):
a=b=1
if nums1[i] >= nums1[i-1]:
a = x+1
if nums1[i] >= nums2[i-1]:
a = max(a,y+1)
if nums2[i] >= nums1[i-1]:
b = x+1
if nums2[i] >= nums2[i-1]:
b = max(b,y+1)
ans = max(ans,a,b)
x,y = a,b
return ans
6919. 使数组中的所有元素都等于零
差分
class Solution:
def checkArray(self, nums: List[int], k: int) -> bool:
n = len(nums)
d = [0]*(n+1)
d[0] = nums[0]
for i in range(1,n):
d[i] = nums[i] - nums[i-1]
for i in range(n-k+1):
# print(i)
if d[i]<0:
# print(i,d[i])
return False
d[i+k] += d[i]
d[i]-=d[i]
# print(d)
if all(v==0 for v in d[:-1]) :
return True
return False
BIT
class BinIndexTreeRUPQ:
"""树状数组的RUPQ模型,结合差分理解"""
def __init__(self, size_or_nums): # 树状数组,下标需要从1开始
# 如果size 是数字,那就设置size和空数据;如果size是数组,那就是a
if isinstance(size_or_nums, int):
self.size = size_or_nums
self.c = [0 for _ in range(self.size + 5)]
else:
self.size = len(size_or_nums)
self.c = [0 for _ in range(self.size + 5)]
for i, v in enumerate(size_or_nums):
self.add_interval(i + 1, i + 1, v)
def add_point(self, i, v): # 单点增加,下标从1开始;不支持直接调用,这里增加的是差分数组的单点
while i <= self.size:
self.c[i] += v
i += i&-i
def sum_prefix(self, i): # 前缀求和,下标从1开始;不支持直接调用,这里求和的是差分数组的前缀和
s = 0
while i >= 1:
s += self.c[i]
i &= i-1
return s
def add_interval(self, l, r, v): # 区间加,下标从1开始,把[l,r]闭区间都加v
self.add_point(l, v)
self.add_point(r + 1, -v)
def query_point(self, i): # 单点询问值,下标从1开始,返回i位置的值
return self.sum_prefix(i)
def lowbit(self, x):
return x & -x
class Solution:
def checkArray(self, nums: List[int], k: int) -> bool:
n = len(nums)
bit = BinIndexTreeRUPQ(nums)
for i in range(n-k+1):
p = bit.query_point(i+1)
if p < 0:
return False
bit.add_interval(i+1,i+k,-p)
if all(bit.query_point(i)==0 for i in range(1,n+1)) :
return True
return False