標籤:ges 建立 子序列和 差值 main 代碼 generated ted void
一、問題描述
令A[1...n]是一個由n個數組成的數組,定義為數組A的插值,其中|a|
表示a的絕對值。設計一個求數組插值的演算法(用偽碼描述)並分析演算法的時間複雜度。
二、解決方案核心思想:
將求數組差值問題轉換為熟知的求數組最大連續子序列和問題。
實現過程:
數組A有n個元素如下:[A0,A1,A2,A3,...,An],我們不妨先做一次轉換,即建立新的數組B,B中有n-1個元素,分別是:
B0=A0-A1;
B1=A1-A2;
B2=A2-A3;
······
Bn-1=An-1-An-2;
假設數組A的差值為|Ai-Aj|,那麼,對應的,|Ai-Aj|=|Bi + Bi+1 +...+ Bj-1|,顯然,求數組A的差值問題就被我們轉換成了求數組B的最大連續子序列和的絕對值的問題。
而通過動態規劃,我們能夠實現演算法複雜度為O(n)。
過程偽碼(JAVA代碼):
public static void main(String[] args) {// TODO Auto-generated method stubArrayList<Integer> A = new ArrayList<Integer>(Arrays.asList(A1,A2,···,An));ArrayList<Integer> B = new ArrayList<Integer>(); //建立數組for (int i = 0 ; i < A.size()-1 ; i++){B.add(A.get(i) - A.get(i+1));} //向數組B中添加元素Ai-Ai+1//動態規劃實現過程int maxhere,maxsum;maxhere=maxsum=B.get(0);for (int i = 1 ; i < B.size() ; i++){if (Math.abs(maxhere+B.get(i)) < Math.abs(B.get(i))){maxhere = B.get(i);} /*如果前面位置到A[i]的最大子序列和絕對值反而比|A[i]|要小,則以當前位置i結尾的最大子序列和為A[i]*/else{maxhere += B.get(i);} /*如果前面位置到A[i]的最大子序列和絕對值要比之前位置的更大,則取最大子序列和絕對值為兩者之和*/if (Math.abs(maxhere) > Math.abs(maxsum)){maxsum = maxhere;} //更新最大子序列和的絕對值}System.out.println(Math.abs(maxsum));}演算法複雜度分析:
建立數組B的演算法複雜度為O(n-1),實現最大子序列和絕對值的演算法複雜度為O(n-1),則總體演算法複雜度為O(n-1)+O(n-1)=O(n),屬於比較快速的演算法。
|萌新想法,如有疏漏,望請大佬指正!
求數組插值——複雜度為O(n)的快速演算法