携手创作,共同成长!这是我参与「掘金日新计划 · 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);
}
}