⭐算法入门⭐《线性枚举》中等02 —— LeetCode 628. 三个数的最大乘积

🙉饭不食,水不饮,题必须刷🙉

C语言免费动漫教程,和我一起打卡!
🌞《光天化日学C语言》🌞

LeetCode 太难?先看简单题!
🧡《C语言入门100例》🧡

数据结构难?不存在的!
🌳《画解数据结构》🌳

闭关刷 LeetCode,剑指大厂Offer!
🌌《LeetCode 刷题指引》🌌

LeetCode 太简单?算法学起来!
💜《夜深人静写算法》💜

一、题目

1、题目描述

  给定一个整型数组 nums,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
  样例输入: nums = [1,2,3]
  样例输出: 6

2、基础框架

  • C语言 版本给出的基础框架代码如下:
int threeNegative(int* nums, int numsSize) {
}

3、原题链接

LeetCode 628. 三个数的最大乘积

二、解题报告

1、思路分析

  三个数的最大乘积,有这么几种情况:
    1、三个负数:排序后,找最接近零的三个数相乘;
    2、两个负数:最大的正数、最小的两个负数;
    3、一个负数:最小的两个正数、最接近零的负数
    4、零个负数:最大的三个正数相乘。

2、时间复杂度

  • 排序后找出,找出正负数的分界点,然后按照上面四个规则分情况讨论,取最大值即可,所以时间复杂度为 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)

3、代码详解

int threeNegative(int* nums, int numsSize) {
    int i;
    for(i = 0; i < numsSize; ++i) {
        if(nums[i] >= 0) {
            break;
        }
    }
    if(i - 3 < 0) {
        return -1000000009;
    }
    return nums[i-1] * nums[i-2] * nums[i-3];
}

int twoNegative(int* nums, int numsSize) {
    int i;
    for(i = 0; i < numsSize; ++i) {
        if(nums[i] >= 0) {
            break;
        }
    }
    if(nums[0] >= 0 || nums[1] >= 0) {
        return -1000000009;
    }
    return nums[0] * nums[1] * nums[numsSize-1];
}

int oneNegative(int* nums, int numsSize) {
    int i;
    for(i = 0; i < numsSize; ++i) {
        if(nums[i] >= 0) {
            break;
        }
    }
    if(i < 1 || i+1 >= numsSize ) {
        return -1000000009;
    }
    return nums[i] * nums[i+1] * nums[i-1];
}


int zeroNegative(int* nums, int numsSize) {
    int i;
    for(i = 0; i < numsSize; ++i) {
        if(nums[i] >= 0) {
            break;
        }
    }
    if(numsSize-3 < i ) {
        return -1000000009;
    }
    return nums[numsSize-1] * nums[numsSize-2] * nums[numsSize-3];
}

int Max(int a, int b) {
    return a > b ? a : b;
}
int comp(const void *a, const void *b) {
    return *(int*)a - *(int*)b;
}

int maximumProduct(int* nums, int numsSize){
    int ans = -1000000009;
    qsort(nums, numsSize, sizeof(int), comp);
    ans = Max(ans, threeNegative(nums, numsSize));  // (1)
    ans = Max(ans, twoNegative(nums, numsSize));    // (2)
    ans = Max(ans, oneNegative(nums, numsSize));    // (3)
    ans = Max(ans, zeroNegative(nums, numsSize));   // (4)
    return ans;
}
  • ( 1 ) (1) (1) 三个负数:排序后,找最接近零的三个数相乘;
  • ( 2 ) (2) (2) 两个负数:最大的正数、最小的两个负数;
  • ( 3 ) (3) (3) 一个负数:最小的两个正数、最接近零的负数;
  • ( 4 ) (4) (4) 零个负数:最大的三个正数相乘。

三、本题小知识

线性枚举的问题,刚开始处理的时候,可以先对数组进行一次排序,有序数组解决时,思路会轻松许多。


  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

英雄哪里出来

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

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

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

打赏作者

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

抵扣说明:

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

余额充值