C语言/数据结构排序题解:三个数的最大乘积——排序后比较两种候选情况

问题描述

在一次数学竞赛中,小C和小红被要求从一个整数数组中找出三个不同的数字,使得它们的乘积最大。但是有一个规则:这三个数字必须来自数组中的不同位置,且不能是同一个数字重复使用(即使数组中有重复数字,每个位置也只能用一次)。小C和小红需要合作设计一个高效的算法来解决这个问题,以便在竞赛中胜出。

要求:

  1. 设计一个算法,时间复杂度为 O(n log n) 或更优,其中 n 是数组的长度。
  2. 考虑数组可能包含正数、负数和零的情况,因为乘积的最大值可能由两个负数和一个正数相乘得到(例如,两个负数相乘为正,再乘以一个正数会更大)。

测试样例

样例1:

输入:nums = [1, 2, 3, 4] 输出:24 解释:最大的三个数字是 2, 3, 4,乘积为 2 * 3 * 4 = 24。

样例2:

输入:nums = [-10, -10, 1, 2, 3] 输出:300 解释:最大的乘积来自两个负数和一个正数:-10 * -10 * 3 = 300。

样例3:

输入:nums = [-1, -2, -3, -4] 输出:-6 解释:所有数字都是负数,乘积最大的是三个最大的负数(即绝对值最小的):-1 * -2 * -3 = -6。

约束条件

  • 3 ≤ nums.length ≤ 10^4
  • -1000 ≤ numsi ≤ 1000
  • 数组中的整数可以是正数、负数或零
  • 保证至少存在三个不同的数字(但可能重复)

程序代码

#include <stdio.h>

#include <stdlib.h>

// 升序比较函数

int cmp(const void* a, const void* b) {

return (*(int*)a) - (*(int*)b);

}

int maximumProduct(int* nums, int numsSize) {

// 升序排序

qsort(nums, numsSize, sizeof(int), cmp);

int n = numsSize;

// 情况1:最大的三个数

int p1 = numsn-1 * numsn-2 * numsn-3;

// 情况2:两个最小的数 × 最大的数

int p2 = nums0 * nums1 * numsn-1;

return p1 > p2 ? p1 : p2;

}

int main() {

int nums1\[\] = {1, 2, 3, 4};

int nums2\[\] = {-10, -10, 1, 2, 3};

int nums3\[\] = {-1, -2, -3, -4};

printf("%d\n", maximumProduct(nums1, 4)); // 24

printf("%d\n", maximumProduct(nums2, 5)); // 300

printf("%d\n", maximumProduct(nums3, 4)); // -6

return 0;

}

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

// 升序比较函数
int cmp(const void* a, const void* b) {
    return (*(int*)a) - (*(int*)b);
}

int maximumProduct(int* nums, int numsSize) {
    // 升序排序
    qsort(nums, numsSize, sizeof(int), cmp);
    
    int n = numsSize;
    
    // 情况1:最大的三个数
    int p1 = nums[n-1] * nums[n-2] * nums[n-3];
    
    // 情况2:两个最小的数 × 最大的数
    int p2 = nums[0] * nums[1] * nums[n-1];
    
    return p1 > p2 ? p1 : p2;
}

int main() {
    int nums1[] = {1, 2, 3, 4};
    int nums2[] = {-10, -10, 1, 2, 3};
    int nums3[] = {-1, -2, -3, -4};
    
    printf("%d\n", maximumProduct(nums1, 4));  // 24
    printf("%d\n", maximumProduct(nums2, 5));  // 300
    printf("%d\n", maximumProduct(nums3, 4));  // -6
    
    return 0;
}

运行结果

相关推荐
another heaven13 小时前
【C/C++ Ranges 是零开销抽象吗?拆开管道、惰性求值和编译期膨胀】
c语言·开发语言·c++
Code_Solitude13 小时前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组
Zwawa17 小时前
让屏幕动起来:OLED动画效果,丝滑光标、帧动画和一只贪吃蛇
c语言·单片机·嵌入式
nice_lcj52018 小时前
LRU 缓存入门:它是什么、怎么用、面试怎么手写
java·数据结构·缓存·面试·lru
꧁细听勿语情꧂19 小时前
直接选择排序,堆排序,冒泡排序,递归快速排序、hoare版本、挖坑法、lomuto前后指针,非递归快速排序
c语言·开发语言·数据结构·算法
cpolar技术支持19 小时前
中文文件名排序跟拼音对不上:os.listdir 返回的是文件系统顺序,三个中文名按字节排结果正好相反
python·文件系统·cpolar·编码·排序
§ꦿCFོ༉1 天前
嵌入式八股文—C语言入门学习(四)
c语言·开发语言·学习
Pniubi1 天前
关于算法用现成数据结构和手撕
数据结构
Severus_black2 天前
【C++初阶】Stack、Queue算法题大练兵!
c语言·c++·算法·stl
唐青枫2 天前
C 语言 strcpy() 用法详解与实战 Demo
c语言