在實現這個算法的時候,想法是假如有一個數組{A,B,C),之后創建一個List存儲{A,A+B,A+B+C);
若要求里面最大的連續數組的時候,用List后面的第i元素減去前面的第z元素的值如果最大的話(保證連續),那就說明從位置z+1到位置i的連續數組有最大的和。然而在情況只有在特殊的情況下,最大值的位置若在最小值之后,並且最小值小於等於0的情況下,用最大值減去最小值即為連續子集最大值(保證最大),其實現的時間復雜度為O(n),若最大值位置在最小值之前,則該算法需要尋找出List數組里面的差值極大值才行。
實現的代碼:
package lainxu; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Scanner; public class ShowM { public static void main(String[] args) { // TODO 自動生成的方法存根 List<Integer> max=new ArrayList<Integer>(); int maxp=-1; //儲存從1開始的子組和最大值的位置 Scanner it=new Scanner(System.in); int num=0; //手動輸入區域 //-------------------------------------------- System.out.println("請輸入你想要查找數組的長度:"); while(num<=0) //實現用戶輸入數組的大小 { if(it.hasNextInt()) { num=it.nextInt(); if(num<=0) { System.out.println("輸入數組不能小於等於0,請重新輸入"); } } else { it.next(); System.out.println("輸入格式錯誤,請重新輸入"); } } //-------------------------------------------- List<Integer> nums=new ArrayList<Integer>(); //用於儲存數組 max.add(0); //添加一個max使其為0 for(int i=1;i<=num;i++) //儲存數組 { //-------------------------------------------- //手動輸入區域 System.out.println("請輸入第"+i+"個數:"); Integer g_down=null; while(g_down==null) { if(it.hasNextInt()) { g_down=it.nextInt(); max.add(g_down+max.get(i-1)); nums.add(g_down); } else { it.next(); System.out.println("輸入格式錯誤,請重新輸入"); } } //-------------------------------------------- } System.out.println("輸入的數組是"+nums.toString()); int minn=max.get(0); int minp=0; int remax=max.get(1); maxp=0; for(int i=1;i<max.size();i++) { List<Integer> max2=max.subList(0, i); int g_min=Collections.min(max2); if(max.get(i)-g_min>remax) { remax=max.get(i)-g_min; maxp=i-1; minp=max.indexOf(g_min); } } System.out.println("最大子數組和為是"+(remax-minn)+",位置為("+(minp+1)+","+(maxp+1)+")"); it.close(); } }
實驗結果:
實驗過程如上