leetcode-数组中两元素的最大乘积

93 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情

题目描述

给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)*(nums[j]-1) 取得最大值。

请你计算并返回该式的最大值。

示例 1:

输入:nums = [3,4,5,2]
输出:12 
解释:如果选择下标 i=1 和 j=2(下标从 0 开始),则可以获得最大值,(nums[1]-1)*(nums[2]-1) = (4-1)*(5-1) = 3*4 = 12

示例 2:

输入:nums = [1,5,4,5]
输出:16
解释:选择下标 i=1 和 j=3(下标从 0 开始),则可以获得最大值 (5-1)*(5-1) = 16

示例 3:

输入:nums = [3,7]
输出:12

提示:

  • 2 <= nums.length <= 500
  • 1 <= nums[i] <= 10^3

思路

题目挺简单的,要求(nums[i]-1)*(nums[j]-1)最大,本质上就是要找到nums[i]和nums[j]最大。当前,这个成立的重要前提是nums[i] >= 1,否则,可能是因为负负得正会更大,那么就需要考虑另外一种情况,(nums[i]-1) < 0 且 (nums[j]-1) < 0,而且它们的绝对值最大。
我们可以使用类似选择法找到最大数的方法,不同的是,我们设置a、b这2个变量,a表示最大值,b表示次大值。初始化a、b的时候,使用数组的前2个元素,然后遍历数组后面的元素,会有如下3种情况:

  • nums[i] > a;这时nums[i]是最大值,a是次大值,需要更新a和b
  • a >= nums[i] > b;这时最大值还是a,次大值是nums[i],需要更新b
  • b >= nums[i];这时最大值还是a,次大值是b,不需要更新

Java版本代码

class Solution {
    public int maxProduct(int[] nums) {
        int a = nums[0], b = nums[1];
        if (b > a) {
            a ^= b;
            b ^= a;
            a ^= b;
        }
        for (int i = 2; i < nums.length; i++) {
            if (nums[i] > a) {
                b = a;
                a = nums[i];
            } else if (nums[i] > b) {
                b = nums[i];
            }
        }
        return (a-1) * (b-1);
    }
}