当前位置: 首页 > news >正文

LeetCode 396 - 旋转函数 (Rotate Function)

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
      • 示例 1
      • 示例 2
    • 题解答案
    • 题解代码分析
      • 代码拆解讲解
        • **1. 先算出 F(0)**
        • **2. 找规律:F(k) 与 F(k-1) 的关系**
        • **3. 迭代更新 F(k)**
    • 示例测试及结果
      • 输出结果:
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

在日常开发中,我们经常需要处理“旋转”、“偏移”、“滑动”这类序列操作,比如日志轮转、时间序列分析、或者数据窗口偏移等。而这道题——LeetCode 396《旋转函数》就是个典型例子,它看起来是一道数学题,但实质上是考察你对数组规律和前后状态转换的理解

这题很容易写出暴力解法(每次旋转都重新计算),但那会超时。
要真正写出高效算法,我们得想办法在O(n) 时间内,复用上一次计算结果,这个思路在数据分析和算法优化中都非常有用。

描述

题目给定一个长度为 n 的整数数组 nums,我们定义:

  • 对数组顺时针旋转 k 次后得到新数组 arr_k

  • 对这个数组计算函数:

    F(k) = 0 * arrk[0] + 1 * arrk[1] + ... + (n - 1) * arrk[n - 1]
    

我们需要找出所有 F(k) 中的最大值。

示例 1

输入: nums = [4,3,2,6]
输出: 26
解释:
F(0) = 25
F(1) = 16
F(2) = 23
F(3) = 26
最大值是 F(3) = 26

示例 2

输入: nums = [100]
输出: 0

题解答案

这题最开始很多人会想:

“我把数组每次旋转一位,然后再计算一遍 F(k) 不就行了吗?”

确实可行,但复杂度是 O(n²),在 n = 10⁵ 时就炸了。

所以我们需要找到更巧的方式来从 F(k-1) 推导出 F(k)

关键发现是:

每次旋转后,数组中所有元素的下标都变化了 1。
我们可以通过数学公式,找出 F(k)F(k-1) 之间的关系。

题解代码分析

先放上完整 Swift 解法

import Foundationclass Solution {func maxRotateFunction(_ nums: [Int]) -> Int {let n = nums.countif n == 0 { return 0 }// 计算数组元素总和let sum = nums.reduce(0, +)// 初始的 F(0)var f0 = 0for i in 0..<n {f0 += i * nums[i]}var maxValue = f0var fk = f0// 利用公式递推计算 F(k)// F(k) = F(k-1) + sum - n * nums[n-k]for k in 1..<n {fk = fk + sum - n * nums[n - k]maxValue = max(maxValue, fk)}return maxValue}
}

代码拆解讲解

我们一步步看清楚算法的推理过程

1. 先算出 F(0)

也就是不旋转的初始值:

for i in 0..<n {f0 += i * nums[i]
}

举例:
nums = [4,3,2,6]
F(0) = 0*4 + 1*3 + 2*2 + 3*6 = 25

2. 找规律:F(k) 与 F(k-1) 的关系

当数组旋转一次时,所有元素的权重(下标)都往后移一位。
于是我们有:

F(k) = F(k-1) + sum(nums) - n * nums[n - k]

解释:

  • sum(nums) 是所有元素的总和;
  • n * nums[n - k] 是被“旋转到头”的元素需要被扣掉的部分。

这一步非常关键,它让我们从 O(n²) 降到了 O(n)。

3. 迭代更新 F(k)

我们只要根据上面这个递推式,不断计算新的 F(k),同时取最大值:

for k in 1..<n {fk = fk + sum - n * nums[n - k]maxValue = max(maxValue, fk)
}

这个循环跑一遍数组就结束了,复杂度只有 O(n)。

示例测试及结果

我们来跑几个例子:

let solution = Solution()print(solution.maxRotateFunction([4,3,2,6]))   // 输出:26
print(solution.maxRotateFunction([100]))       // 输出:0
print(solution.maxRotateFunction([1,2,3,4,5])) // 输出:40

输出结果:

26
0
40

解释:

  • [4,3,2,6] → 最大 F(k) = 26;
  • [100] → 只有一个数,无论怎么旋转都是 0;
  • [1,2,3,4,5] → 最大值出现在最后一次旋转时。

时间复杂度

整个算法只遍历数组两次:

  1. 一次计算总和;
  2. 一次计算递推 F(k)。

所以时间复杂度为 O(n)

这比暴力计算的 O(n²) 提速了几个数量级。

空间复杂度

只用到几个变量(sum、f0、fk、maxValue),没有额外数据结构。

所以空间复杂度是 O(1),非常高效。

总结

这道题表面是“数组旋转”,实质是一个数学公式优化问题
关键在于你能不能发现 F(k)F(k-1) 的线性关系。

一旦抓住了 F(k) = F(k-1) + sum - n * nums[n - k] 这个规律,整个题目立刻变得优雅又高效。

在实际开发中,这种“从前一个状态推下一个状态”的技巧非常常见,比如:

  • 时间序列分析中,用上一个窗口结果推下一个;
  • 滑动平均计算中,用上次结果减去旧值加上新值;
  • 性能优化时,减少重复计算。
http://www.dtcms.com/a/474129.html

相关文章:

  • 服装公司网站策划书网站无法连接服务器
  • 【C++篇】:LogStorm——基于多设计模式下的同步异步高性能日志库项目
  • php怎么做网站怎么做试玩平台推广网站
  • go语言:在 Win10上,如何编译 ffuf-v2.1.0?
  • 做网站没装数据库建站 网站程序
  • 有哪些做高考模拟卷的网站做第一个网站什么类型
  • Maven 设置项目编码,防止编译打包出现编码错误
  • 【Linux】文件系统之缓冲区
  • 【检索:数据库】6、B+树数据库索引全解析:如何为海量磁盘数据构建毫秒级检索系统
  • 创意设计公司网站dede一键更新网站出错
  • 使用Python高效读取ZIP压缩文件中的UTF-8 JSON数据到Pandas和PySpark DataFrame
  • 基于Spring Boot + Vue 3的乡村振兴综合服务平台性能优化与扩展实践
  • 基于单片机的声光控制楼道灯(论文+源码)
  • 网站运营分析云平台网站建设方案
  • 【Linux】进程间同步与互斥(下)
  • 现成的手机网站做APP手机网站开发教程pdf
  • 【栈】5. 验证栈序列(medium)
  • Leetcode之 Hot 100
  • 建立能网上交易的网站多少钱wordpress调取多个分类文章
  • MySQL 索引:原理、分类与操作指南
  • Blender机箱盒体门窗铰链生成器资产预设 Hingegenious
  • 网站托管就业做美食有哪些网站
  • 神经符号AI的深度探索:从原理到实践的全景指南
  • 零食网站建设规划书建行输了三次密码卡锁怎么解
  • Python代码示例
  • 济南市历下区建设局官方网站wordpress高级套餐
  • ALLEGRO X APD版图单独显示某一网络的方法
  • 计算机网络基础篇——如何学习计算机网络?
  • 电子商务网站建设的总体设计wordpress dux主题5.0版本
  • 《jEasyUI 创建简单的菜单》