旋转函数:纵览「前缀和 + 滑动窗口」精妙应用
2023-11-29 03:46:29
旋转函数的魅力:美妙的数组变换
旋转函数的定义可谓独具匠心:给定一个非空整数数组 nums,其旋转函数 F(k) 被定义为:
F(k) = 0 * nums[0] + 1 * nums[1] + ... + (n - 1) * nums[n - 1] + n * nums[0] + (n - 1) * nums[1] + ... + 2 * nums[n - 1]
其中 n 是数组 nums 的长度。
换句话说,旋转函数 F(k) 的值等于将数组 nums 向右旋转 k 步后,每个元素与其下标的乘积之和。
「前缀和 + 滑动窗口」:强强联合,所向披靡
解决这道难题的妙招在于巧妙地融合「前缀和」与「滑动窗口」这两种强有力的算法技巧。
- 前缀和:蓄势待发,一触即发
前缀和数组的前缀和 preSum[i] 定义为数组 nums 从下标 0 到下标 i 的元素之和,即:
preSum[i] = nums[0] + nums[1] + ... + nums[i]
利用前缀和数组,我们可以轻松地计算出数组 nums 旋转 k 步后的前缀和数组 preSum[i + k]。
- 滑动窗口:纵横驰骋,收放自如
滑动窗口算法是一种高效的动态规划方法,它可以帮助我们在线性时间内解决许多问题。
在本题中,我们可以使用滑动窗口来维护一个大小为 n 的窗口,窗口内包含数组 nums 的前 n 个元素。
当我们计算 F(k) 时,我们可以通过滑动窗口来高效地计算窗口内的元素与其下标的乘积之和。
算法流程:循序渐进,步步为营
-
初始化 :计算数组 nums 的前缀和数组 preSum。
-
滑动窗口 :使用滑动窗口来维护一个大小为 n 的窗口,窗口内包含数组 nums 的前 n 个元素。
-
计算 F(k) :通过滑动窗口来高效地计算窗口内的元素与其下标的乘积之和,并将结果存储在数组 F 中。
-
寻找最大值 :遍历数组 F,找到最大的值,即为旋转函数的最大值。
代码实现:匠心独运,巧夺天工
def maxRotateFunction(nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
preSum = [0] * n
preSum[0] = nums[0]
for i in range(1, n):
preSum[i] = preSum[i - 1] + nums[i]
F = [0] * n
F[0] = sum(nums)
for k in range(1, n):
F[k] = preSum[n - 1] - preSum[n - k - 1] + k * nums[n - k]
return max(F)
# 测试用例
nums = [4, 3, 2, 6]
print(maxRotateFunction(nums)) # 输出:26
结语:拨云见日,豁然开朗
通过「前缀和 + 滑动窗口」的强强联合,我们成功地解决了 LeetCode 上的 396. 旋转函数,并得到了问题的答案。
从这道题中,我们领略了算法之美,并对「前缀和 + 滑动窗口」组合拳的妙用叹为观止。
希望这篇文章能对您有所启发,也希望您能继续探索算法的奥秘,不断精进自己的编程技能。