一個整形數組中最大值求和問題
要求:
1.輸入一個整形數組,數組裏面有正數也有負數。
2.數組中國連續的一個或多個整數組成一個子數組,每個子數組都有一個和。
3.求所有子數組的和的最大值。要求時間復雜度為O(n)。
當自己看到這個題目的時候,想到了“復雜的問題簡單化,一步一步來”,然後在課上老師的引導之下有了自己實現這個功能的方法。最終自己用了兩者方法實現功能,但是在第二種方法上花費的時間較多,幾乎是第一種方法兩倍的時間。下面將兩種方法一一解釋自己的思路。
一、時間復雜度O(n^2)
本次功能實現簡單,一共分為3步,首先是實現數組的輸入,然後進行一個或多個連續子數組的求和,最後進行比較。但需要註意的是,求和以及比較是同時存在的。
本次實現功能的過程中遇到了一個小小的問題,就是將自己用來記錄最大值的變量f賦初值為0,忽略了數組中的值全為負數時的情況,最終解決將f賦初值為數組中第一個數,解決了問題。
以下是完整代碼以及測試結果:
import java.util.Scanner; public class sum01 { public static void main(String[] args) { // TODO Auto-generated method stub //整形數組的輸入 Scanner sc = new Scanner(System.in); System.out.println("請輸入數組的長度為:"); int n=sc.nextInt(); int[] c = new int[n]; System.out.println("請輸入"+n+"個整數"); for(int i=0;i<n;i++) { c[i] = sc.nextInt(); } //子數組求和以及大小比較 int f=c[0];//定義整形變量f,為子數組最大值 int sum=0;//定義整形變量sum,為子數組求和for (int j=0;j<n;j++) { for (int i=j;i<n;i++) { sum=sum+c[i]; if(f<sum) { f=sum;//每次求和之後將sum與已有的最大值進行比較 } } sum=0; } System.out.println("該數組的子數組之和的最大值為:"+f); }
二、時間復雜度O(n)
第二種方案就是實現要求中時間復雜度為O(n)的問題,該程序的設計思想是,從數組中第一個值開始進行加法運算,如果sum值加到某數為負(包括數組中所有整數為負的情況),則將sum值歸0(因為數組的子數組為連續,所以sum值可以直接歸0),如果sum值大於已有的最大值f,那麽給f賦新值sum,如此循環直至數組遍歷一遍,最終如果sum不為零,則計算結果就是最大整數,若sum值為0,才需二次遍歷數組尋找數組中的最大值。
以下是完整代碼以及測試結果:
import java.util.Scanner; public class sum02 { public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner(System.in); System.out.println("請輸入數組的長度為:"); int n=sc.nextInt(); int[] c = new int[n]; System.out.println("請輸入"+n+"個整數"); for(int i=0;i<n;i++) { c[i] = sc.nextInt(); } int f=0;//定義整形變量f,為子數組最大值 int sum=0;//定義整形變量sum,為子數組求和 for(int i=0;i<n;i++) { sum = sum+c[i]; if(sum < 0) { sum=0; } if(sum > f) { f = sum; } } if(sum == 0) { for(int i=0;i<n;i++) { if(i == 0) { f = c[i]; } if(f < c[i]) { f = c[i]; } } } System.out.println("該數組的子數組之和的最大值為:"+f); } }
此外,在課上還有許多同學提出了自己的觀點,首先將數組的最大值找出,然後在圍繞最大值進行求和運算的方法也是可行的,但自己還沒有用代碼進行實現,但同學的設計思路自己已經明白了。
一問多解,像極了自己以前熱愛的數學問題,生活中許多問題也是這樣,真神奇!
一個整形數組中最大值求和問題