1. 程式人生 > >求數組插值——復雜度為O(n)的快速算法

求數組插值——復雜度為O(n)的快速算法

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)的快速算法