编程之美2.13——子数组的最大乘积

给定义个长度为N的整数数组,只允许用乘法,不能用除法,计算在任意(N-1)的个数的组合中乘积最大的一组。

【思路】

突然变成了雅黑,挺不习惯的~~还是雅黑好看?ω?

实现起来很简单,但我是不会想到这样的思路的……看来除了积累别想着有别的途径来提高了π__π

1.用空间换时间,开数组s和t,分别保存从前向后的连乘结果和从后向前的连乘结果。对于每个排除了第i个元素的N-1个元素组合p[i],

有p[i]=s[i-1]*t[i+1],求得所有的p[i],遍历一次即可得最大值。

2.假设N个整数的乘积为P,对P进行正负分析:

1)P=0

数组中至少含有一个0,假设出去该0之外,其他N-1个数的乘积为Q,再根据Q的正负性讨论:

a。Q=0:数组至少有两个0,N-1个数的乘积只能为0,返回0;

b。Q>0:返回Q;

c。Q<0:用0替代任意数值为0,返回0.

2)P>0

如果数组中存在正数,则去掉最小正数,若数组全是负数,则去掉绝对值最大负数。

3)P<0

由负负得正,N个元素去掉一个负数,乘积得到一个正数,则需去掉一个绝对值最小的负数。

【codes】

法一:

int maxMulti(int N[], int n)
{
    int *s=new int[n+1];
    int *t=new int[n+1];
    int *p=new int[n];
    int remax=INT_MIN;
    s[0]=1;
    t[n]=1;
    for(int i=1; i<=n; i++)
        s[i]=s[i-1]*N[i-1];
    for(int i=n-1; i>=0; i--)
        t[i]=t[i+1]*N[i];
    for(int i=0; i<n; i++){
        p[i]=s[i-1]*t[i+1];
        if(p[i]>remax)
            remax=p[i];
    }
    delete [] s;
    delete [] t;
    delete [] p;
    return remax;
}

法二:

int maxMulti1(int N[], int n)
{
    int multi=1;
    for(int i=0; i<n; i++)
        multi*=N[i];
    if(multi==0){
        int q=1;
        int count=0;
        for(int i=0; i<n; i++)
            if(N[i]!=0){
                q*=N[i];
                count++;
            }
        if(count<n-1) return 0;
        else if((count==n-1)&&(q>0)) return q;
        else if((count==n-1)&&(q<0)) return 0;
    }
    else if(multi>0){
        int r=0;
        int j;
        for(int i=0; i<n; i++)
            if(N[i]>r){
                r=N[i];
                j=i;
            }
        if(r==0)
            for(int i=0; i<n; i++)
                if(abs(N[i])>r){
                    r=abs(N[i]);
                    j=i;
                }
        int q=1;
        for(int i=0; i<n&&i!=j; i++)
            q*=N[i];
        return q;
    }
    else if(multi<0){
        int r=0;
        int j;
        for(int i=0; i<n; i++)
            if(abs(N[i]>r)){
                r=abs(N[i]);
                j=i;
            }
        int q=1;
        for(int i=0; i<n&&i!=j; i++)
            q*=N[i];
        return q;
    }
}

【评价】

题目很简单,但思路想不出。第二种方法写的冗长了。

时间: 2024-10-14 00:35:47

编程之美2.13——子数组的最大乘积的相关文章

编程之美2.13 子数组的最大乘积

      这道题目是求 n-1 个数的最大乘积,即数组大小为 n,则会存在 n 个 n-1 的连续数字,那么,我们需要寻找的是最大的那一个乘积.       其实看到题目,感觉很简单,循环走两遍数组就可以得到结果,但是,那样的话,复杂度是平方量级的,如果一个数组中元素很多,那么,时间效率上是不能接受的,所以,需要重新思考问题,寻找简洁的解法.       这里,我们可以利用辅助数组的办法,把需要乘在一起的数字保存下来,单独的放到数组中,然后乘在一块就可以了,这样说起来其实不是那么容易理解,我还

编程之美2.13 子数组最大乘积

问题描述: 给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合乘积中最大的一组,并写出算法的时间复杂度. 解法: 1.暴力解法------O(n^2) 2.前后缀法------O(n) 3.统计法--------O(n) 具体思路和代码: 1.暴力解法: 思路:利用两层循环,依次删掉一个,其余的做乘法,计算出最大的. 代码: 1 int s1(int A[], int n) 2 { 3 int s = 1; 4 int max; 5 for(int i = 1;

编程之美2.13 最大子阵列产品

      这个问题是目前正在寻求 n-1 最大的产品编号.该数组的大小 n.它会存在 n 一个 n-1 连续数.然后,我们需要找到一个最大的产品.       事实上看到题目,感觉非常easy,循环走两遍数组就能够得到结果,可是,那样的话,复杂度是平方量级的,假设一个数组中元素非常多.那么,时间效率上是不能接受的.所以,须要又一次思考问题.寻找简洁的解法.       这里.我们能够利用辅助数组的办法,把须要乘在一起的数字保存下来.单独的放到数组中,然后乘在一块就能够了.这样说起来事实上不是那

【编程之美】2.13 子数组的最大乘积

题目:一个有N个数的整数数组 取其中N-1个元素的子数组 求子数组的最大乘积 不能用除法. 这道题自己没有写对,没有考虑到负数的情况,只是单纯的想去掉最小的数. 但是若有负数 -5 -4 -3 中-5 * -4 = 20更大. 需要先统计正数.负数和0的个数,再分类讨论.考察的其实就是细心和耐心. //答案解法 int getMaxProductAnswer(int * a, int alen) { int NumPositive = 0; int NumNegtive = 0; int Num

2.13 子数组的最大乘积

题目: 给定一个长度为N的整形数组,只允许用乘法,不能用除法.计算任意N-1个数的组合中乘积最大的一组. 方法一: #include <iostream> #define MAXN 10000 using namespace std; int n, a[MAXN], s[MAXN], t[MAXN], p[MAXN]; //s[i]表示数组前i个元素的乘积 //t[i]表示数组后N-i个元素的乘积 //p[i] = s[i-1] * t[i+1]; //p[i]表示数组除第I个元素外,其他N-

【目录】编程之美

编程之美 2.1 二进制数中1的个数 2.2 阶乘 2.4 1的数目 2.5 寻找最大的k个数 2.6 精确表达浮点数 2.7求最大公约数 2.8 找符合条件的整数 2.10 求数组中最大的数和最小的数 2.12快速寻找满足条件的两个数 2.13 子数组的最大乘积 2.14 求数组的子数组之和的最大值 2.15 子数组之和的最大值(二维) 2.16 求数组的最大递增子序列 2.17 数组循环位移 2.18 数组分割 2.19 区间重合判断 2.20程序理解和时间分析 2.21 只考加法的面试题

编程之美2.14 求数组的子数组之和的最大值

问题描述: 一个有N个整数元素的一维数组(A[0], A[1], A[2],...,A[n-1]),这个数组当然有很多子数组,那么子数组之和的最大值是什么呢? 解法: 1. 暴力解法-------O(N^3) 2. 改进版暴力解法-------O(N^2) *3. 分治算法-------O(NlogN)(暂时未去实现) 4. 数组间关系法-------O(N) 具体思路和代码: 1.暴力解法 思路:Sum[i,...,j]为数组第i个元素到第j个元素的和,遍历所有可能的Sum[i,...,j].

编程之美2.17 数组循环移位

问题描述: 设计一个算法,把一个含有N元素的数组循环左移或者右移K位. 解决方法: 1. 暴力解法------O(KN) 2. 颠倒位置------O(N) 具体思路和代码: 1. 暴力解法------O(KN) 思路:循环K次,每次移动一位 代码: 1 //右移 2 void s1(int A[], int n, int k) 3 { 4 k = k % n; 5 for(int i = 0; i < k; i++) 6 { 7 int t = A[n-1]; 8 for(int j = n-

编程之美leetcode之编辑距离

Edit Distance Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.) You have the following 3 operations permitted on a word: a) Insert a character b) Delete a char