力扣中的线性扫描

/*

        力扣每日一题628题的官方解中提到了一种“线性扫描”的方法。通过这种方法,无需通过排序,并且只需遍历一遍数组,即可找到最大最小值。深入剖析后,发现这种方法还是很巧妙的。

*/

/*

        题目:

*/

官方解是这样的:

class Solution {
public:
    int maximumProduct(vector<int>& nums) {
        // 最小的和第二小的
        int min1 = INT_MAX, min2 = INT_MAX;
        // 最大的、第二大的和第三大的
        int max1 = INT_MIN, max2 = INT_MIN, max3 = INT_MIN;

        for (int x: nums) {
            if (x < min1) {
                min2 = min1;
                min1 = x;
            } else if (x < min2) {
                min2 = x;
            }

            if (x > max1) {
                max3 = max2;
                max2 = max1;
                max1 = x;
            } else if (x > max2) {
                max3 = max2;
                max2 = x;
            } else if (x > max3) {
                max3 = x;
            }
        }

        return max(min1 * min2 * max1, max1 * max2 * max3);
    }
};

1.初始化变量:

        min1和min2分别用来维护数组中 “最小” 和 “次小” 的元素,用INT_MAX初始化;

        max1、max2、max3分别维护数组中 “最大”、“第二大”、“第三大”的元素,用INT_MIN初始化。

        初学者可能有这样的疑问,为什么要用表示最大整数的MAX来初始化min变量,而用MIN来初始化max变量呢?因为后续我们在遍历数组的过程中,需要不断更新这几个变量,这样看似反向操作实则是为了安全地更新。

        假如用MIN初始化min1和min2,而我们现在遍历到6这个数,要先比较6和min1或min2的大小,而6是绝无可能小于MIN的,所以min1和min2在后面的遍历中,永远不会更新。

        这样想想是不是更清晰了一些呢?

2.遍历数组:for (int x: nums)

        这种for循环的遍历方法称为 “基于范围的for循环” ,其语法如下:

        for(declaration:sequence){

               //loop

        }

        declaration是变量声明,即每次遍历你可以理解为我们用了一个int x变量去接收当前遍历的变量;sequence是序列,可以是数组、向量、字符串等容器。

        可以这么打个比方,我们在学c++迭代器的时候最常见的一种迭代器遍历的for循环语句是这样写的:

        for(vector<int>::iterator it=nums.begin();it!=nums.end();it++)

        这句用基于范围的for循环可以简化为auto自动推导类型的:

        for(auto it:nums)

3.循环主体:

        以下用res来表示当前遍历到的数组元素。 

        分别进行两次大的判断,即:①和小的比,并更新min1和min2;②和大的比,并更新max1、max2和max3。       

        ①res先和min1比大小,如果res小,就将res赋给min1,作为最小的;如果比min1大,那res就不能当最小的;那我们看看它能不能当次小,即和min2比较,如果比min2小,那就将res赋给min2,作为次小的;如果它比min2还大,那res就不能更新min1和min2的值。

        ②res再和max1比,如果比max1大,就将res赋给max1,作为最大的;如果不大于max1而大于max2,那就让res做次大的;如果不大于max2而大于max3,那就让res做第三大的;如果都不大于的话,res就不能更新max1~3的值。

4.返回值:

        对于本题来讲,这个最大的乘积只有两种情况:

        ①三个最大的数相乘;

        ②两个最小的数(一定是负数)和一个最大的数相乘;

        对于包含0的情况亦如此,这就是一个数学问题了,这里我们不再赘述。

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值