用递推归纳法,求解《396. 旋转函数》

旋转函数递推公式推导过程:每次加和减去 n 乘以 nums[n-k]

递推公式

f(k) = f(k - 1) + sum - n * nums[n - k] // 如上图所示

例题

396. 旋转函数

给定一个长度为 n 的整数数组 nums 。 假设 arrk 是数组 nums 顺时针旋转 k 个位置后的数组,我们定义 nums 的 旋转函数 F 为: F(k) = 0 arrk[0] + 1 arrk[1] + ... + (n - 1) * arrk[n - 1] 返回 F(0), F(1), ..., F(n-1)中的最大值 。 生成的测试用例让答案符合 32 位 整数。

答案

var maxRotateFunction = function(nums) {
  const n = nums.length
  let sum = f = 0
  for (let i = 0; i < n; i++) {
    sum += nums[i]
    f += i * nums[i]
  }
  let r = f
  for (let i = 1; i < n; i++) {
    f += sum - n * nums[n - i]
    if (f > r) r = f
  }
  return r
};
func maxRotateFunction(nums []int) int {
  n, sum, f := len(nums), 0, 0
  for i, v := range nums {
    sum += v
    f += v * i
  }
  r := f
  for i := 1; i < n; i++ {
    f += sum - n * nums[n - i]
    if f > r {
      r = f
    }
  }
  return r
}
class Solution {
    function maxRotateFunction($nums) {
      $sum = $f = 0;
      foreach ($nums as $i => $v) {
        $sum += $v;
        $f += $v * $i;
      }
      $n = count($nums);
      $r = $f;
      for ($i = 1; $i < $n; $i++) {
        $f += $sum - $n * $nums[$n - $i];
        if ($f > $r) $r = $f;
      }
      return $r;
    }
}
二分查找(对数运算 + 前缀和),滑动窗口:求解《713. 乘积小于 K 的子数组》
根据对数运算性质将相乘转为求和问题,用前缀和优化。二分查找,滑动窗口,求解《713. 乘积小于 K 的子数组》
双指针合并有序数组:求解《88. 合并两个有序数组》和《面试题 10.01. 合并排序的数组》
双指针合并有序数组(合并数组),注意数组越界不同语言的处理方式。求解《88. 合并两个有序数组》和《面试题 10.01. 合并排序的数组》
二维数组自定义函数排序 + 栈:按二维数组自定义函数升序排序,使用栈合并区间,求解《56. 合并区间》和《剑指 Offer II 074. 合并区间》
按二维数组自定义函数升序排序,使用栈合并区间,求解《56. 合并区间》和《剑指 Offer II 074. 合并区间》