求數組插值——復雜度為O(n)的快速算法
阿新 • • 發佈:2017-09-28
ring 創建 絕對值 stub () ·· 代碼 img 描述
一、問題描述
令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 stub ArrayList<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)的快速算法