最大乘积问题|豆包MarsCode AI刷题

41 阅读3分钟

97 最大乘积问题

问题描述

小R手上有一个长度为 n 的数组 (n > 0),数组中的元素分别来自集合 [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]。小R想从这个数组中选取一段连续的区间,得到可能的最大乘积。

你需要帮助小R找到最大乘积的区间,并输出这个区间的起始位置 x 和结束位置 y (x ≤ y)。如果存在多个区间乘积相同的情况,优先选择 x 更小的区间;如果 x 相同,选择 y 更小的区间。

注意:数组的起始位置为 1,结束位置为 n

思路分析

  1. 考虑到乘积之后的数值特别大,观察集合中的数都满足2的指数、则乘积可以替换为加法。
  2. 最大乘积的终止条件为出现0时,那么乘积则一直为0,则遇到0时,则进行判断
  3. 由于x,y都需要最小,那么则还需要考虑为1时,乘积没有变化,但是区间增大了

代码

import java.util.Arrays;
public class Main {
    public static int[] solution(int n, int[] data) {
        int start = 1, end = 1;
        int max = 0;
        int l = 0, r = 0, sum = 0;
        for (int i = 0; i < n; i++) {
            if (data[i] == 0) {
                if (sum > max) {
                    max = sum;
                    start = l + 1;
                    end = r;
                }
                l = i + 1;
                sum = 0;
            } else if (data[i] != 1) {
                sum += (int)(Math.log(data[i]) / Math.log(2));
                r = i + 1;
            }
        }
        if (sum > max) {
            start = l + 1;
            end = r;
        }
        return new int[]{start, end};
    }

    public static void main(String[] args) {
        // Add your test cases here
        System.out.println(Arrays.equals(solution(5, new int[]{1, 2, 4, 0, 8}), new int[]{1, 3}));
        System.out.println(Arrays.equals(solution(7, new int[]{1, 2, 4, 8, 0, 256, 0}), new int[]{6, 6}));
    }
}

复杂度分析

  • 时间复杂度:O(n),因为我们需要遍历整个排列一次。
  • 空间复杂度:O(1),因为我们只使用了常数级的额外空间。

后续优化

想知道要快速判断一个数是否是2的幂,并且如果是,得到它是2的几次方,可以使用位运算。具体来说,一个数 n 是2的幂,当且仅当 n & (n - 1) == 0,并且 n > 0。然后,可以通过计算 log2(n) 来得到它是2的几次方。

在Java中,可以使用以下方法来快速判断一个数是否是2的幂,并得到它是2的几次方:

public class Main {
    public static int log2(int n) {
        return (int) (Math.log(n) / Math.log(2));
    }

    public static void main(String[] args) {
        int n = 64;
        if ((n & (n - 1)) == 0 && n > 0) {
            int power = log2(n);
            System.out.println(n + " 是 2 的 " + power + " 次方");
        } else {
            System.out.println(n + " 不是 2 的幂");
        }
    }
}

解释:

  1. 判断是否是2的幂(n & (n - 1)) == 0 && n > 0

    • n & (n - 1) 的结果为0,表示 n 是2的幂。
    • n > 0 确保 n 是正数。
  2. 计算2的几次方log2(n)

    • 使用 Math.log(n) / Math.log(2) 计算 n 是2的几次方。

注意:

  • 这种方法适用于判断任意整数是否是2的幂,并计算它是2的几次方。
  • 对于题目中的特定集合 [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024],可以直接使用数组索引来判断和计算。