题目:​​原题链接​(中等)

标签:贪心算法、树状数组

解法

时间复杂度

空间复杂度

执行用时

Ans 1 (Python)

O ( N l o g N )

O ( N l o g N )

7532ms (5.32%)

Ans 2 (Python)

Ans 3 (Python)

解法一:

class Solution:
def minMoves(self, nums: List[int], limit: int) -> int:
size = len(nums)

# 树状数组及相关函数
tree = [0] * (limit * 2 + 1)

def add(k, x):
while k <= limit * 2:
tree[k] += x
k += k & (-k)

def range_add(l, r, x):
add(l, x)
add(r + 1, -x)

def query(k: int) -> int:
ans = 0
while k > 0:
ans += tree[k]
k -= k & (-k)
return ans

min_val, max_val = 2, 200001 # 可以生成的最小值

for i in range(size // 2):
j = (size - 1) - i

v1, v2 = nums[i], nums[j]

# 2次操作可以得到的最大值
val5 = (v1 if v1 > limit else limit) + (v2 if v2 > limit else limit)
# 1次操作可以得到的最大值
if v1 > limit and v2 > limit:
val4 = v1 + v2
elif v1 > limit >= v2:
val4 = v1 + limit
elif v1 <= limit < v2:
val4 = limit + v2
else: # v1 < limit and v2 < limit
val4 = max(v1, v2) + limit
# 0次操作可以得到的值
val3 = v1 + v2
# 1次操作可以得到的最小值
if v1 > limit and v2 > limit:
val2 = v1 + v2
elif v1 > limit >= v2:
val2 = v1 + 1
elif v1 <= limit < v2:
val2 = 1 + v2
else: # v1 < limit and v2 < limit
val2 = min(v1, v2) + 1
# 2次操作可以得到的最小值
val1 = (v1 if v1 > limit else 1) + (v2 if v2 > limit else 1)

# 更新最大值、最小值
min_val = max(min_val, val1)
max_val = min(max_val, val5)

# 更新树状数组
range_add(val1, val2 - 1, 2)
range_add(val2, val3 - 1, 1)
range_add(val3 + 1, val4, 1)
range_add(val4 + 1, val5, 2)

# print(v1, v2, "->", val1, val2, val3, val4, val5, "(", min_val, max_val, ")", "->",
# [query(i) for i in range(limit * 2 + 1)])

# 计算最终结果
ans = 200001
for i in range(min_val, min(limit * 2, max_val) + 1):
ans = min(ans, query(i))
# print(i, ":", query(i))
return ans