• LC-396. 旋转函数(前缀和+滑动窗口、动态规划)


    396. 旋转函数

    难度中等243

    给定一个长度为 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 位 整数。

    示例 1:

    输入: nums = [4,3,2,6]
    输出: 26
    解释:
    F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
    F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
    F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
    F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26
    所以 F(0), F(1), F(2), F(3) 中的最大值是 F(3) = 26 。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    示例 2:

    输入: nums = [100]
    输出: 0
    
    • 1
    • 2

    提示:

    • n == nums.length
    • 1 <= n <= 105
    • -100 <= nums[i] <= 100

    前缀和 + 滑动窗口

    题解:https://leetcode.cn/problems/rotate-function/solution/by-ac_oier-sxbi/

    题目要对「旋转数组」做逻辑,容易想到将 n u m s nums nums 进行复制拼接,得到长度为 2 ∗ n 2 * n 2n 的新数组,在新数组上任意一个长度为 $n $ 的滑动窗口都对应了一个旋转数组。

    当窗口往后移动一位,也就是窗口的右端点来到 i + n i + n i+n 的位置,左端点来到 i + 1 i + 1 i+1 的位置。

    不难发现,随着窗口的逐步右移,每一位公共部分的权值系数都会进行减一。

    公共部分的差值为 ∑ i d x = i + 1 i + n − 1 n u m s [ i d x ] \sum_{idx = i + 1}^{i + n - 1}nums[idx] idx=i+1i+n1nums[idx],这引导我们可以使用前缀和进行优化。

    至此,我们从旧窗口到新窗口的过渡,都是 O ( 1 ) O(1) O(1),整体复杂度为 O ( n ) O(n) O(n)

    实现上,我们并不需要真正对 n u m s nums nums 进行复制拼接,而只需要在计算前缀和数组 s u m sum sum 进行简单的下标处理即可。

    class Solution {
        public int maxRotateFunction(int[] nums) {
            int n = nums.length;
            int[] sum = new int[n*2+1];
            for(int i = 1; i <= 2*n; i++){
                // (i-1)%n,对下标进行处理,以实现旋转数组2*n的前缀和
                sum[i] = sum[i-1] + nums[(i-1)%n];
            }
            int ans = 0;
            for(int i = 1; i <= n; i++){
                //根据F的定义,先把初始值求出来
                ans += nums[i-1]*(i-1);
            }
            for(int i = n+1,cur = ans; i < 2*n; i++){
                cur += nums[(i-1) % n]*(n-1); // 加上出现在窗口右端点的值(n - 1) * arrk[n - 1]
                cur -= sum[i-1] - sum[i-n]; // 权重系数都减了1 = 减去窗口内的和
                if(cur > ans) ans = cur;
            }
            return ans;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    找规律+动态规划

    // 找规律题
    // sum:                            a0 * 1 + a1 * 1 + a2 * 1 + a3 * 1
    
    // f(0):                              a0 * 0 + a1 * 1 + a2 * 2 + a3 * 3
    // f(0) + sum:                        a0 * 1 + a1 * 2 + a2 * 3 + a3 * 4  
    
    // f(1):                     a3 * 0 + a0 * 1 + a1 * 2 + a2 * 3              f(1) = f(0) + sum - 4*a[4-1]
    // f(1) + sum:               a3 * 1 + a0 * 2 + a1 * 3 + a2 * 4
    
    // f(2):            a2 * 0 + a3 * 1 + a0 * 2 + a1 * 3                   f(2) = f(1) + sum - 4*a[4-2]
    // f(2) + sum:      a2 * 1 + a3 * 2 + a0 * 3 + a1 * 4 
    
    // f(3):  a1 * 0 +  a2 * 1 + a3 * 2 + a0 * 3                        f(3) = f(2) + sum - 4*a[4-3]
    
    // 由上可得f(n) = f(n - 1) + sum - len * a[len - n]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    class Solution:
        def maxRotateFunction(self, nums: List[int]) -> int:
            n = len(nums)
            cur = sum([i * nums[i] for i in range(n)])
            ans = cur
            total = sum(nums)
    
            for i in range(n - 1):
                cur = cur + n * nums[i] - total
                if cur > ans:
                    ans = cur
    
            return ans  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    vue实战-分页器
    如何进行MDM的产品测试
    考研时间规划和激励语句
    洛谷P1307 数字反转 C语言
    开源与闭源:AI模型发展的两条路径
    Linux权限
    vue3在路由route.js中获取不到仓库pinia中store里面的值
    【前端指南】Axios框架与应用
    新版Java面试专题视频教程——多线程篇②
    Shopee(虾皮)什么产品好做?2022美妆/美容工具热销及需求品类推荐!
  • 原文地址:https://blog.csdn.net/qq_42958831/article/details/128142262