拼多多内推笔试一:求数组中任意三个数的最大乘积

来源:互联网 发布:佛教电影知乎 编辑:程序博客网 时间:2024/04/27 15:00

这是leetcode上的的原题
https://leetcode.com/problems/maximum-product-of-three-numbers/description/
因为数组中可能有正数、负数和0,所以解题思路是:找出最小的两个负数和最大的正数相乘 以及三个最大的正数相乘 ,两者取其中最大值。
1、原leetcode中的解题代码:

class Solution {public:    int maximumProduct(vector<int>& nums) {        sort(nums.begin(),nums.end());        int len=nums.size();        return max(nums[0]*nums[1]*nums[len-1],nums[len-3]*nums[len-2]*nums[len-1]);         }};

2、针对这次笔试的牛客网上的代码:
要求时间复杂度O(n), 空间复杂度O(1)。分治法
其实就是使用了5次快速排序中的partition函数,找到符合位置的那5个数,所以时间复杂度从O(nlogn)变成了O(n)

#include <cstdio>#include <iostream>#include <string>#include <algorithm>using namespace std;const int N = 1e6 + 10;long long a[N];int k;int partition(int l,int r) {    while(l != r)    {        while(a[r] >= a[l] && r > l)            r--;        if(l == r)            break;        swap(a[r],a[l]);        while(a[l] < a[r] && r > l)            l++;        if(l < r)            swap(a[r],a[l]);    }    return l;}long long solve(int l,int r) {    int now = partition(l,r);    if(k < now)        return solve(l,now-1);    else if(k > now)        return solve(now+1,r);    else        return a[now];}int main() {    int n;    while(~scanf("%d", &n)) {        for(int i = 0; i < n; ++i) {            scanf("%lld", &a[i]);        }        k = n - 1;        long long x1 = solve(0, n-1);        k = n - 2;        long long x2 = solve(0, n-2);        k = n - 3;        long long x3 = solve(0, n-3);        long long Ans = x1 * x2 * x3;        if(n > 3) {            k = 0;            long long y1 = solve(0, n-1);            k = 1;            long long y2 = solve(0, n-2);            Ans = max(Ans, y1*y2*x1);        }        printf("%lld\n", Ans);    }    return 0;}

参考链接:
http://tieba.baidu.com/p/5099192704
牛客上的牛人解答:
https://www.nowcoder.com/discuss/30697?type=0&order=0&pos=17&page=2
https://www.nowcoder.com/discuss/30693?type=0&order=0&pos=25&page=1

阅读全文
0 0