本文最后更新于 3 分钟前,文中所描述的信息可能已发生改变。
3688. 偶数的按位或运算 - 力扣(LeetCode)
题目类型
#遍历
解题思路
参考:这道题很简单!
示例代码
python
class Solution:
def evenNumberBitwiseORs(self, nums: List[int]) -> int:
ans = 0
for x in nums:
if x % 2 == 0:
ans |= x
return ans3689. 最大子数组总值 I - 力扣(LeetCode)
题目类型
#脑经急转弯
解题思路
参考:这道题很简单!
示例代码
python
class Solution:
def maxTotalValue(self, nums: List[int], k: int) -> int:
return (max(nums) - min(nums)) * k3690. 拆分合并数组 - 力扣(LeetCode)
题目类型
#哈希 #BFS
解题思路
根据数据范围,至多有 6!=720 个不同的排列,这很小,考虑暴力。
示例代码
python
class Solution:
def minSplitMerge(self, nums1: List[int], nums2: List[int]) -> int:
n = len(nums1)
memo = {tuple(nums1)}
q = [nums1]
for ans in count(0):
tmp = q
q = []
for nums in tmp:
if nums == nums2:
return ans
for i in range(n):
for j in range(i + 1, n + 1):
m = j - i
a = nums[: i] + nums[j:]
for k in range(n - m + 2):
if k == i:
continue
b = a[: k] + nums[i: j] + a[k: ]
c = tuple(b)
if c not in memo:
memo.add(c)
q.append(b)3691. 最大子数组总值 II - 力扣(LeetCode)
题目类型
#堆 #线段树 #ST表
解题思路
数组的最值一定被子数组包含,所以可以从数组到子数组进行枚举,同时使用数据结构计算子数组最值之差,并采用堆维护当前最大值。
示例代码
python
class Solution:
def maxTotalValue(self, nums: List[int], k: int) -> int:
n = len(nums)
h = []
mxt = SparseTable(nums, max)
mnt = SparseTable(nums, min)
def query(l: int, r: int) -> int:
return mxt.query(l, r) - mnt.query(l, r)
for i in range(n):
heappush(h, (-query(i, n - 1), i, n - 1))
ans = 0
while k:
k -= 1
x, l, r = heappop(h)
ans -= x
if l == r:
continue
s = query(l, r - 1)
heappush(h, (-s, l, r - 1))
return anspython
min = lambda a, b: b if b < a else a
max = lambda a, b: b if b > a else a
def op(a: Tuple[int, int], b: Tuple[int, int]) -> Tuple[int, int]:
return min(a[0], b[0]), max(a[1], b[1])
class ST:
def __init__(self, a: List[int]):
n = len(a)
sz = n.bit_length()
st = [[None] * sz for _ in range(n)]
for i, x in enumerate(a):
st[i][0] = (x, x)
for j in range(1, sz):
for i in range(n - (1 << j) + 1):
st[i][j] = op(st[i][j - 1], st[i + (1 << (j - 1))][j - 1])
self.st = st
# [l, r) 左闭右开
def query(self, l: int, r: int) -> int:
k = (r - l).bit_length() - 1
mn, mx = op(self.st[l][k], self.st[r - (1 << k)][k])
return mx - mn
class Solution:
def maxTotalValue(self, nums: List[int], k: int) -> int:
n = len(nums)
st = ST(nums)
h = [(-st.query(i, n), i, n) for i in range(n)]
heapify(h)
ans = 0
for _ in range(k):
x, l, r = h[0]
if x == 0:
break
ans -= x
heapreplace(h, (-st.query(l, r - 1), l, r - 1))
return anspy
from functools import reduce
from math import lcm, gcd
from operator import or_, and_
class SparseTable:
def __init__(self, lst, fun):
"""static range queries can be performed as long as the range_merge_to_disjoint fun satisfies monotonicity"""
n = len(lst)
self.bit = [0] * (n + 1)
self.fun = fun
self.n = n
for i in range(2, n + 1):
self.bit[i] = self.bit[i >> 1] + 1
for i in range(n+1):
assert self.bit[i] == (i.bit_length() - 1 if i else i.bit_length())
self.st = [[0] * n for _ in range(self.bit[-1] + 1)]
self.st[0] = lst
for i in range(1, self.bit[-1] + 1):
for j in range(n - (1 << i) + 1):
self.st[i][j] = fun(self.st[i - 1][j], self.st[i - 1][j + (1 << (i - 1))])
def query(self, left, right):
"""index start from 0"""
assert 0 <= left <= right < self.n
pos = self.bit[right - left + 1]
return self.fun(self.st[pos][left], self.st[pos][right - (1 << pos) + 1])
def bisect_right(self, left, val, initial):
"""index start from 0"""
assert 0 <= left < self.n
# find the max right such that st.query(left, right) >= val
pos = left
pre = initial # 0 or (1<<32)-1
for x in range(self.bit[-1], -1, -1):
if pos + (1 << x) - 1 < self.n and self.fun(self.st[x][pos], pre) >= val: # can by any of >= > <= <
pre = self.fun(self.st[x][pos], pre)
pos += (1 << x)
# may be pos=left and st.query(left, left) < val
if pos > left:
pos -= 1
else:
pre = self.st[0][left]
assert left <= pos < self.n
return pos, pre
def bisect_right_length(self, left):
"""index start from 0"""
assert 0 <= left < self.n
# find the max right such that st.query(left, right) < right-left+1
pos = left
pre = 0
for x in range(self.bit[-1], -1, -1):
if pos + (1 << x) - 1 < self.n and self.fun(self.st[x][pos], pre) > pos + (1 << x) - left:
pre = self.fun(self.st[x][pos], pre)
pos += (1 << x)
if pos == left and self.st[0][pos] == 1:
return True, pos
if pos < self.n and self.fun(pre, self.st[0][pos]) == pos + 1 - left:
return True, pos
return False, pos