leetcode
leetcode 2501 ~ 2550
子数组的最大 GCD-Sum

子数组的最大 GCD-Sum

难度:

标签:

题目描述

代码结果

运行时间: 1219 ms, 内存: 25.6 MB


/*
 * Leetcode Problem 2941: Maximum GCD-Sum of Subarray
 * 
 * Problem Description: 
 * Given an array of positive integers, find the maximum sum of any subarray such that the GCD (Greatest Common Divisor) of the elements in the subarray is greater than 1.
 * 
 * Solution Approach using Java Streams: 
 * 1. Generate all possible subarrays using IntStream.
 * 2. For each subarray, calculate the GCD using reduce method.
 * 3. Filter subarrays with GCD greater than 1 and calculate their sum.
 * 4. Track the maximum sum among all valid subarrays.
 */

import java.util.stream.IntStream;

public class MaximumGCDSubarraySumStream {
    // Helper method to compute the GCD of two numbers
    private static int gcd(int a, int b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    public static int maxGCDSum(int[] nums) {
        return IntStream.range(0, nums.length)
                .flatMap(i -> IntStream.rangeClosed(i, nums.length - 1)
                        .mapToObj(j -> IntStream.rangeClosed(i, j).map(k -> nums[k]).toArray())
                        .filter(subarray -> IntStream.of(subarray).reduce(nums[i], MaximumGCDSubarraySumStream::gcd) > 1)
                        .mapToInt(subarray -> IntStream.of(subarray).sum())
                )
                .max()
                .orElse(0);
    }

    public static void main(String[] args) {
        int[] nums = {3, 6, 9, 15};
        System.out.println(maxGCDSum(nums)); // Output: 33
    }
}

解释

方法:

此题解采用了动态规划和哈希表的混合策略来解决问题。基本思路是通过遍历数组,持续更新以每个元素为结尾的子数组的最大GCD和其对应的和与长度。使用哈希表来存储当前所有可能的GCD值及其对应的最大和与子数组长度。对于每个新的元素x,更新哈希表,检查与之前每个子数组的最大公约数,并更新这些公约数的最大和与长度。如果达到子数组长度k,计算可能的答案。这种方法确保了我们能够找到长度至少为k的子数组的最大GCD-Sum。

时间复杂度:

O(n^2)

空间复杂度:

O(n)

代码细节讲解

🦆
在算法中,为什么要单独处理`k为1`的情况,直接返回最大元素的平方?
当`k`为1时,每个单独的元素都可以视为一个符合条件的子数组,因此我们只需要找到数组中的最大元素。因为题目要求计算最大GCD和的平方,而单个元素的GCD是其本身,所以最大元素的GCD和就是最大元素本身,其平方即为答案。这种情况下不需要进行更复杂的动态规划计算,直接返回最大元素的平方可以大大简化问题并提高算法效率。
🦆
算法中使用的`gcd`函数是如何确保在更新哈希表时保持计算效率的?
在算法中,`gcd`函数用于计算两个数的最大公约数。计算最大公约数的经典算法是欧几里得算法,其时间复杂度非常低,平均情况下是O(log(min(a, b)))。在更新哈希表时,我们需要对每个新元素和已有的每个GCD进行计算,使用高效的`gcd`函数可以确保即使这一步骤在每次迭代中重复多次,总体的计算效率仍然是可接受的。
🦆
在更新哈希表时,如何决定是否创建新的GCD键或更新现有键的值?
哈希表中的键是子数组的GCD值。在更新哈希表时,首先计算当前元素与已存在GCD的最大公约数。如果这个GCD值不在哈希表中,我们将创建一个新的键,并初始化其对应的和与子数组长度。如果这个GCD值已存在于哈希表中,我们将比较现有的和与新计算的和,选择较大的和来更新,同时更新对应的子数组长度。这种方法确保了哈希表始终存储了对应GCD的最大和与最大长度,从而在后续步骤中可以更有效地找到可能的最大GCD和。
🦆
对于每个GCD键的值,您选择存储最大和与子数组长度,这种选择的优点是什么?
存储每个GCD对应的最大和与子数组长度的策略,可以在遍历数组时持续追踪和更新每种GCD条件下可能的最优解。这允许算法在后续的遍历中快速比较和选择不同GCD下的最优子数组情况,特别是当需要判断子数组长度是否满足题目条件(例如长度至少为k)时。此外,这种存储方式还可以在达到所需子数组长度时,立即计算出当前GCD与其和的乘积,从而实时更新可能的最大GCD-Sum答案。这有助于降低整体的时间复杂度并提高算法效率。

相关问题