給乙個浮點數序列,取最大乘積連續子串的值,例如 -2.5,4,0,3,0.5,8,-1,則取出的最大乘積連續子串為3,0.5,8。也就是說,上述陣列中,3 0.5 8這3個數的乘積3*0.5*8=12是最大的,而且是連續的。
思路1:
暴力法:將所有的可能都羅列出來,時間複雜度為o(n^2)
double maxproductsubstring(double *data, int n)
} }return maxresult;
}
思路二:
利用動態規劃的方法:由於在陣列中有正數和負數,所以需要記錄最大的乘積和最小的乘積,maxend和minend,最小乘積乘以乙個負數可能成為最大乘積,利用狀態轉移方程進行計算:
maxend = max(max(maxend*a[i],minend*a[i]),a[i]);
minend = min (min(maxend*a[i],minend*a[i]),a[i]);
對於元素a[i],在0-i中,要麼是與maxend相乘之後變為最大乘積,要麼與minend相乘變成最大乘積,或者本身就是最大乘積。
初始化都為a
double maxproductsubstring_dynamic(double *data, int n)
return maxresult;
}
思路二:
一空間換時間,利用兩個陣列s,t,s[i]記錄0-i元素的乘積,t[i]代表i-n-1元素的乘積,那麼去除a[i]後的乘積是s[i-1]*t[i+1],由於只需要掃瞄兩遍陣列,所以時間複雜度是線性的o(n)
int maxn_1productsubstring2(int *data, int const n)
int maxresult = s[0] * t[2];
for(int i=1;imaxresult)
maxresult = r;
} return maxresult;
}
在上述的基礎上,可以進行邏輯判斷,減少計算量:
假設n個整數的乘積為p,針對p的正負性進行如下分析(其中,an-1表示n-1個數的組合,pn-1表示n-1個數的組合的乘積)。
1.p為0
那麼,陣列中至少包含有乙個0。假設除去乙個0之外,其他n-1個數的乘積為q,根據q的正負性進行討論:q為0說明陣列中至少有兩個0,那麼n-1個數的乘積只能為0,返回0;
q為正數
返回q,因為如果以0替換此時an
-1中的任乙個數,所得到的pn
-1為0,必然小於q;
q為負數
如果以0替換此時an
-1中的任乙個數,所得到的pn
-1為0,大於q,乘積最大值為0。
2. p為負數
根據「負負得正」的乘法性質,自然想到從n個整數中去掉乙個負數,使得pn3. p為正數-1為乙個正數。而要使這個正數最大,這個被去掉的負數的絕對值必須是陣列中最小的。我們只需要掃瞄一遍陣列,把絕對值最小的負數給去掉就可以了。
類似地,如果陣列中存在正數值,那麼應該去掉最小的正數值,否則去掉絕對值最大的負數值。
上面的解法採用了直接求n個整數的乘積p,進而判斷p的正負性的辦法,但是直接求乘積在編譯環境下往往會有溢位的危險(這也就是本題要求不使用除法的潛在用意),事實上可做乙個小的轉變,不需要直接求乘積,而是求出陣列中正數(+)、負數(-)和0的個數,從而判斷p的正負性,其餘部分與以上面的解法相同。
在時間複雜度方面,由於只需要遍歷陣列一次,在遍歷陣列的同時就可得到陣列中正數(+)、負數(-)和0的個數,以及陣列中絕對值最小的正數和負數,時間複雜度為o(n)。
#define max_postive 100
#define min_negative -100
int maxn_1productsubstring3(int *data, int const n)
int num_zero=0,num_postive=0,num_negative=0;
int position_min_postive,position_max_negative,position_zero;
int min_postive = max_postive;
int max_negative = min_negative;
for(int k=0;k0)
}else
}} int maxresult;
if(num_zero != 0)
else
maxresult = 0;
}else
}else
else
}return maxresult;
}
最大連續子乘積
寫文章只是為了整理思路嗎,在遠古的學生時代,可能只是為了機試參加個比賽什麼的,作為一屆老人,早已沒了會點啥就想拿出來炫耀的年紀,會點除了能混過面試,是不是也能和面試官聊出點感情,程式似乎無可避免悄然而然成了我們生活中心 相顧兩無言,唯把 談。朦朧週末早上起床,昨晚與老友聊此題記憶猶新。今日把遞推式子...
最大連續子串行乘積
問題描述 給定乙個整數序列 可能有正數,0和負數 求它的乙個連續最大子串行乘積,如果乘積為負數,輸出 1 分析 假設陣列為a,直接利用動歸來求解,考慮到可能存在負數的情況,我們用max i 來表示以a i 結尾的最大連續子串行的乘積值,用min i 表示以a i 結尾的最小的連續子串行的乘積值,那麼...
最大連續子串行乘積
推薦 題目描述 給定乙個浮點數序列 可能有正數 0和負數 求出乙個最大的連續子串行乘積。輸入 輸入可能包含多個測試樣例。每個測試樣例的第一行僅包含正整數 n n 100000 表示浮點數序列的個數。第二行輸入n個浮點數用空格分隔。輸入資料保證所有數字乘積在雙精度浮點數表示的範圍內。輸出 對應每個測試...