【leetcode-1464】

1464.LeetCode - 数组中两元素的最大乘积 Maximum Product of Two Elements in an Array


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

Given the array of integers nums, you will choose two different indices i and j of that array. Return the maximum value of (nums[i]-1)*(nums[j]-1).

链接:https://leetcode-cn.com/problems/maximum-product-of-two-elements-in-an-array/



题目分析

很多刚接触刷题的同学可能会想到简单的暴力枚举方法,枚举出所有的可能情况再取最大值。但会这样会会有两层循环,时间复杂度为O(n^2) 。所以我们要选择一些取巧的方法,充分利用题目的有利条件

  • 1.由于数组规定全部为正数 可以对数组排序 Arrays.sort(nums)。取最末尾的两个值就能得到最大的值。API快速排序的时间复杂度O(nlogn)
  • 2.把求最大值的问题转换成,求最大值和次最大值的这两个子问题,这样我们最多只需遍历两次数组。就可以获得最大的answer。
  • 3.还有没有只遍历一次数组就同时获取 最大值和次最大值呢。当然是有的。

一、time O(n) 枚举一遍数组

每次比较过程中,一定会产生最大值的。
我们维护两个 记录最大值和次最大值的索引变量 maxInddex, preMaxIndex;
如果maxIndex发生了替换,那么被替换的maxIndex就变成次最大值preMaxIndex
如果maxIndex没有变动(nums[maxIndex] > nums[i]),nums[i] 与 nums[preMaxIndex]中产生次最大值,那么preMaxIndex与每个元素比较取最大 (i != j)
此解法 O(n) 打败100%
需要注意的是 两个变量的初始值不能相同。maxIndex 一定要设置成数组的起始位置。

public static int maxProduct(int[] nums){
        if(nums.length <= 2) return (nums[0]-1)*(nums[1]-1);
        int maxIndex = 0;
        // 在每次比较过程中,一定会产生最大值的。if maxIndex发生了替换,么就变成次最大值
        int preMaxIndex = 1;
        for (int i = 1; i < nums.length; i++) {
            if (nums[maxIndex] < nums[i]) {
                preMaxIndex = maxIndex;
                maxIndex = i;
            }else{
                preMaxIndex = nums[preMaxIndex] > nums[i]? preMaxIndex:i;
            }
        }
        return (nums[maxIndex]-1)*(nums[preMaxIndex]-1);
    }

}

二、time O(n) 遍历两遍数组

O(n)
利用冒泡排序的思想,在每次遍历中,比较相邻位置的两个元素,把大的元素放到后面的位置
这样在遍历两次后,数组末尾的两个数一定是最大的

public static int maxProduct(int[] nums){
        if(nums.length <= 2) return (nums[0]-1)*(nums[1]-1);
        //获取最大值和次最大值的下标
        int maxIndex = 0;
        int secondIndex = 0;
        //尝试不进行交换,交互需要耗时
        for (int i = 0; i < nums.length; i++) {
            maxIndex = nums[maxIndex] > nums[i] ? maxIndex:i;
        }
        //把最大放到末尾
        int temp = nums[nums.length-1];
        nums[nums.length-1] = nums[maxIndex];
        nums[maxIndex] = temp;
        for (int i = 0; i < nums.length-1; i++) {
            secondIndex = nums[secondIndex] > nums[i]?secondIndex:i;
        }
        return (nums[nums.length-1]-1)*(nums[secondIndex]-1);
    }

三、API 快速排序

O(nlogn)

public static int maxProduct(int[] nums){
	Arrays.sort(nums);
	return (nums[nums.length-1]-1)*(nums[nums.length-2]-1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值