nums
, you will choose two different indices i
and j
of that array. Return the maximum value of (nums[i]-1)*(nums[j]-1)
.
Example 1:
Input: nums = [3,4,5,2] Output: 12 Explanation: If you choose the indices i=1 and j=2 (indexed from 0), you will get the maximum value, that is, (nums[1]-1)*(nums[2]-1) = (4-1)*(5-1) = 3*4 = 12.
Example 2:
Input: nums = [1,5,4,5] Output: 16 Explanation: Choosing the indices i=1 and j=3 (indexed from 0), you will get the maximum value of (5-1)*(5-1) = 16.
Example 3:
Input: nums = [3,7] Output: 12
Constraints:
2 <= nums.length <= 500
1 <= nums[i] <= 10^3
The problem asks to find the maximum product of two distinct elements in an array after subtracting 1 from each element. We can solve this efficiently using several approaches.
Understanding the Problem
The key insight is that to maximize the product (nums[i] - 1) * (nums[j] - 1)
, we need to select the two largest numbers from the input array nums
. Subtracting 1 from each before multiplying ensures that we are considering the largest possible difference in values.
Approach 1: Brute Force
This approach iterates through all possible pairs of distinct elements in the array, calculates the product, and keeps track of the maximum product encountered.
Approach 2: Sorting
This approach sorts the array in descending order and then takes the product of the two largest elements (after subtracting 1 from each). Sorting allows us to efficiently find the two largest elements without comparing all pairs.
Approach 3: Linear Scan
This approach iterates through the array only once, keeping track of the two largest elements encountered so far. This is the most efficient approach as it avoids sorting.
Code Examples (Python)
Here are implementations of approaches 2 and 3 in Python:
Approach 2 (Sorting):
class Solution:
def maxProduct(self, nums: List[int]) -> int:
nums.sort(reverse=True) # Sort in descending order
return (nums[0] - 1) * (nums[1] - 1)
Approach 3 (Linear Scan):
class Solution:
def maxProduct(self, nums: List[int]) -> int:
max1 = 0
max2 = 0
for num in nums:
if num > max1:
max2 = max1
max1 = num
elif num > max2:
max2 = num
return (max1 - 1) * (max2 - 1)
Other Languages:
The same approaches can be implemented in other languages (Java, C++, JavaScript, etc.). The core logic remains the same; the primary difference lies in the syntax and available libraries for sorting. For instance, in Java, you would use Arrays.sort()
for Approach 2, and in C++, you'd use std::sort()
.
Choosing the Best Approach
For this problem, Approach 3 (Linear Scan) is the most efficient due to its O(n) time complexity and O(1) space complexity. It's generally preferred unless the array is already sorted (or the sorting is done for other reasons in the code). Approach 2 is acceptable if you already have a need to sort the array for other operations. Approach 1 should be avoided unless the array is very small.