排序题目:数组中两元素的最大乘积

题目

标题和出处

标题:数组中两元素的最大乘积

出处:1464. 数组中两元素的最大乘积

难度

2 级

题目描述

要求

给定一个整数数组 nums \texttt{nums} nums,可以选择数组的两个不同下标 i \texttt{i} i j \texttt{j} j。返回 ( nums[i] − 1 ) × ( nums[j] − 1 ) (\texttt{nums[i]} - \texttt{1}) \times (\texttt{nums[j]} - \texttt{1}) (nums[i]1)×(nums[j]1) 的最大值。

示例

示例 1:

输入: nums   =   [3,4,5,2] \texttt{nums = [3,4,5,2]} nums = [3,4,5,2]
输出: 12 \texttt{12} 12
解释:如果选择下标 i   =   1 \texttt{i = 1} i = 1 j   =   2 \texttt{j = 2} j = 2(下标从 0 \texttt{0} 0 开始),则可以获得最大值, ( nums[1] − 1 ) × ( nums[2] − 1 ) = ( 4 − 1 ) × ( 5 − 1 ) = 3 × 4 = 12 (\texttt{nums[1]} - \texttt{1}) \times (\texttt{nums[2]} - \texttt{1}) = (\texttt{4} - \texttt{1}) \times (\texttt{5} - \texttt{1}) = \texttt{3} \times \texttt{4} = \texttt{12} (nums[1]1)×(nums[2]1)=(41)×(51)=3×4=12

示例 2:

输入: nums   =   [1,5,4,5] \texttt{nums = [1,5,4,5]} nums = [1,5,4,5]
输出: 16 \texttt{16} 16
解释:选择下标 i = 1 \texttt{i} = \texttt{1} i=1 j = 3 \texttt{j} = \texttt{3} j=3(下标从 0 \texttt{0} 0 开始),则可以获得最大值 ( 5 − 1 ) × ( 5 − 1 ) = 16 (\texttt{5} - \texttt{1}) \times (\texttt{5} - \texttt{1}) = \texttt{16} (51)×(51)=16

示例 3:

输入: nums   =   [3,7] \texttt{nums = [3,7]} nums = [3,7]
输出: 12 \texttt{12} 12

数据范围

  • 2 ≤ nums.length ≤ 500 \texttt{2} \le \texttt{nums.length} \le \texttt{500} 2nums.length500
  • 1 ≤ nums[i] ≤ 10 3 \texttt{1} \le \texttt{nums[i]} \le \texttt{10}^\texttt{3} 1nums[i]103

解法一

思路和算法

由于数组 nums \textit{nums} nums 中至少有两个元素,因此一定存在两个不同的下标。

由于数组 nums \textit{nums} nums 中的元素都是正整数,为了使得乘积最大,应该选择最大的两个元素。

将数组升序排序之后,数组的末尾两个元素即为最大的两个元素,使用末尾两个元素计算乘积即为最大乘积。

代码

class Solution {
    public int maxProduct(int[] nums) {
        Arrays.sort(nums);
        int length = nums.length;
        return (nums[length - 1] - 1) * (nums[length - 2] - 1);
    }
}

复杂度分析

  • 时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n n n 是数组 nums \textit{nums} nums 的长度。排序需要 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间。

  • 空间复杂度: O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是数组 nums \textit{nums} nums 的长度。排序需要 O ( log ⁡ n ) O(\log n) O(logn) 的递归调用栈空间。

解法二

思路和算法

由于计算最大乘积只需要得到数组中最大的两个元素,并不需要得到所有元素的顺序,因此可以直接遍历数组找到最大的两个元素。

使用两个变量 first \textit{first} first second \textit{second} second 分别表示第一大元素和第二大元素,初始化为 int \texttt{int} int 类型的最小值,确保初始值小于数组中的任意元素。遍历数组 nums \textit{nums} nums,对于每个元素 num \textit{num} num,依次与 first \textit{first} first second \textit{second} second 比较并更新 first \textit{first} first second \textit{second} second 的值,确保 first \textit{first} first second \textit{second} second 的值等于已经遍历的元素中最大的两个元素。遍历结束之后, first \textit{first} first second \textit{second} second 的值等于数组中最大的两个元素值,使用这两个值计算最大乘积。

代码

class Solution {
    public int maxProduct(int[] nums) {
        int first = Integer.MIN_VALUE, second = Integer.MIN_VALUE;
        for (int num : nums) {
            if (num > first) {
                second = first;
                first = num;
            } else if (num > second) {
                second = num;
            }
        }
        return (first - 1) * (second - 1);
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。需要遍历数组一次。

  • 空间复杂度: O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值