1. 解题思路
这一题思路上还是挺巧妙的,主要就是一个累计数组的思路。
对于任意两个数
x
,
y
x, y
x,y,如果通过一次变换,那么我们能够获得的差值的区间为:
[
m
a
x
(
0
,
m
i
n
(
x
−
k
,
y
−
k
)
)
,
m
a
x
(
x
,
y
,
k
−
x
,
k
−
y
)
]
[max(0, min(x-k, y-k)), max(x, y, k-x, k-y)]
[max(0,min(x−k,y−k)),max(x,y,k−x,k−y)]
而在这个区间之外,我们则需要两次操作才能够获得我们的目标差值(如果可以通过变换得到的话)。
唯一的例外就是 ∣ x − y ∣ |x-y| ∣x−y∣这个数,我们不需要任何操作就能够直接得到了。
因此,我们构造一个累加数组,统计一下每一个数字的pair在各个区间当中所需要的变化次数,最后累积求和一下就能够获得对应变换到各个差值下所需要的变换次数,然后我们取出其中的最小值即可。
需要注意的是,原则上我们还需要讨论一下无法变换得到的区间将其变化赋值为 ∞ \infty ∞,不过考虑到我们本就是要取最小值,因此这里就没有具体去讨论了。
2. 代码实现
给出python代码实现如下:
class Solution:
def minChanges(self, nums: List[int], k: int) -> int:
n = len(nums)
m = max(max(nums), k)
cnt = [0 for _ in range(m+2)]
for i in range(n//2):
x, y = nums[i], nums[n-1-i]
diff = abs(x-y)
_min = min(max(0, x-k), max(0, y-k))
_max = max(x, y, k-x, k-y)
cnt[_min] += 1
cnt[_max+1] -= 1
if _min > 0:
cnt[0] += 2
cnt[_min] -= 2
cnt[_max+1] += 2
if _min <= diff <= _max:
cnt[diff] -= 1
cnt[diff+1] += 1
else:
cnt[diff] -= 2
cnt[diff+1] += 2
for i in range(m+1):
cnt[i+1] += cnt[i]
return min(cnt)
提交代码评测得到:耗时906ms,占用内存30.9MB。