日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

最大子段和问题Java实现

發(fā)布時(shí)間:2023/12/18 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最大子段和问题Java实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最大子段和問題

一、問題描述
  給定長(zhǎng)度為n的整數(shù)序列,a[1...n], 求[1,n]某個(gè)子區(qū)間[i , j]使得a[i]+…+a[j]和最大。

  例如(-2,11,-4,13,-5,2)的最大子段和為20,所求子區(qū)間為[2,4],子序列是(11,-4,13),最大子段和是20。

二、解決方法

1、窮舉法(初級(jí)版):SimpleAlgorithmOfMaximumIntervalSumLow.java

  最容易理解,

  用三重循環(huán),可遍歷所有子區(qū)間,一個(gè)表示起始位置,一個(gè)表示終點(diǎn)位置,一個(gè)求當(dāng)前子序列的和 1 package cn.com.zfc.everyday.test; 2 3 /** 5 * 6 * @title SimpleAlgorithmOfMaximumSegmentSumLow 7 * @describe 最大子段和的簡(jiǎn)單算法的初級(jí)版 8 * @author 張富昌 9 * @date 2017年4月9日下午10:45:51 10 */ 11 public class SimpleAlgorithmOfMaximumIntervalSumLow { 12 // 最大子段和的首元素在原序列中的位置 13 private static int startIndex; 14 // 最大子段和的尾元素在原序列中的位置 15 private static int endIndex; 16 17 public static void main(String[] args) { 18 // 原序列 19 int[] array = { -2, 11, -4, 13, -5, -2 }; 20 System.out.println("原序列是:"); 21 // 輸出原序列 22 printSegment(0, array.length - 1, array); 23 // 求最大子段和 24 int maxSum = maxSum(array); 25 System.out.println("最大字段和:" + maxSum); 26 System.out.println("最大子段和的首元素在原序列中的位置:" + startIndex + ",最大子段和的尾元素在原序列中的位置:" + endIndex); 27 System.out.println("最大字段和的子序列式:"); 28 // 輸出最大子段和序列 29 printSegment(startIndex, endIndex, array); 30 } 31 32 /** 33 * 34 * @param array:原序列 35 * @return:最大子段和 36 */ 37 private static int maxSum(int[] array) { 38 // 假設(shè)最大子段和為 0 39 int maxSum = 0; 40 // 雙重 for 循環(huán)遍歷所有的子序列 41 for (int i = 0; i < array.length; i++) { 42 for (int j = 0; j < array.length; j++) { 43 // 一個(gè) for 循環(huán)求當(dāng)前子序列的和 44 int currentSum = 0; 45 for (int k = i; k <= j; k++) { 46 currentSum += array[k]; 47 } 48 if (currentSum > maxSum) { 49 maxSum = currentSum; 50 // 最大子段和的首元素在原序列中的位置 51 startIndex = i; 52 // 最大子段和的尾元素在原序列中的位置 53 endIndex = j; 54 } 55 } 56 } 57 return maxSum; 58 } 59 60 /** 61 * 輸出序列 62 * 63 * @param start:序列的開始下標(biāo) 64 * @param end:序列的結(jié)束下標(biāo) 65 * @param array:要輸出的序列 66 */ 67 private static void printSegment(int start, int end, int[] array) { 68 for (int i = start; i <= end; i++) { 69 System.out.print(array[i] + " "); 70 } 71 System.out.println(); 72 } 73 74 }

2、窮舉法(升級(jí)版):SimpleAlgorithmOfMaximumIntervalSumHigh.java

 避免子序列的重復(fù)計(jì)算

1 package cn.com.zfc.everyday.test; 2 3 /** 4 * 5 * @title SimpleAlgorithmOfMaximumIntervalSumHigh 6 * @describe 最大子段和的簡(jiǎn)單算法的升級(jí)版 7 * @author 張富昌 8 * @date 2017年4月9日下午11:17:33 9 */ 10 public class SimpleAlgorithmOfMaximumIntervalSumHigh { 11 // 最大子段和的首元素在原序列中的位置 12 private static int startIndex; 13 // 最大子段和的尾元素在原序列中的位置 14 private static int endIndex; 15 16 public static void main(String[] args) { 17 // 原序列 18 int[] array = { -2, 11, -4, 13, -5, -2 }; 19 System.out.println("原序列是:"); 20 // 輸出原序列 21 printSegment(0, array.length - 1, array); 22 // 求最大子段和 23 int maxSum = maxSum(array); 24 System.out.println("最大字段和:" + maxSum); 25 System.out.println("最大子段和的首元素在原序列中的位置:" + startIndex + ",最大子段和的尾元素在原序列中的位置:" + endIndex); 26 System.out.println("最大字段和的子序列式:"); 27 // 輸出最大子段和序列 28 printSegment(startIndex, endIndex, array); 29 } 30 31 /** 32 * 33 * @param array:原序列 34 * @return:最大子段和 35 */ 36 private static int maxSum(int[] array) { 37 // 假設(shè)最大子段和為 0 38 int maxSum = 0; 39 // 雙重 for 循環(huán)遍歷所有的子序列 40 for (int i = 0; i < array.length; i++) { 41 // 當(dāng)前序列的和 42 int currentSum = 0; 43 // 注意 j 的初始值,避免重復(fù)計(jì)算 44 for (int j = i; j < array.length; j++) { 45 currentSum += array[j]; 46 if (currentSum > maxSum) { 47 maxSum = currentSum; 48 // 最大子段和的首元素在原序列中的位置 49 startIndex = i; 50 // 最大子段和的尾元素在原序列中的位置 51 endIndex = j; 52 } 53 } 54 } 55 return maxSum; 56 } 57 58 /** 59 * 輸出序列 60 * 61 * @param start:序列的開始下標(biāo) 62 * @param end:序列的結(jié)束下標(biāo) 63 * @param array:要輸出的序列 64 */ 65 private static void printSegment(int start, int end, int[] array) { 66 for (int i = start; i <= end; i++) { 67 System.out.print(array[i] + " "); 68 } 69 System.out.println(); 70 } 71 72 }

3、分治算法:BranchAlgorithmOfMaximumIntervalSum.java

1 package cn.com.zfc.everyday.test; 2 3 /** 4 * 5 * @title BranchAlgorithmOfMaximumIntervalSum 6 * @describe 最大子段和的分治算法: 7 * 所有子區(qū)間[start, end]只可能有以下三種可能性: 8 * 在[1,n/2]這個(gè)區(qū)域內(nèi) 9 * 在[n/2+1,n]這個(gè)區(qū)域內(nèi) 10 * 起點(diǎn)位于[1,n/2],終點(diǎn)位于[n/2+1,n]內(nèi) 11 * 以上三種情形的最大者,即為所求. 12 * 前兩種情形符合子問題遞歸特性,所以遞歸可以求出. 對(duì)于第三種情形,則需要單獨(dú)處理. 13 * 第三種情形必然包括了n/2和n/2+1兩個(gè)位置,這樣就可以利用第二種窮舉的思路求出: 14 * 以n/2為終點(diǎn),往左移動(dòng)擴(kuò)張,求出和最大的一個(gè)startSum,以n/2+1為起點(diǎn),往右移動(dòng)擴(kuò)張,求出和最大的一個(gè)endSum 15 * startSum + endSum是第三種情況可能的最大值 16 * @author 張富昌 17 * @date 2017年4月9日下午10:46:32 18 */ 19 public class BranchAlgorithmOfMaximumIntervalSum { 20 21 public static void main(String[] args) { 22 // 原序列 23 int[] array = { -2, 11, -4, 13, -5, -2 }; 24 System.out.println("原序列是:"); 25 // 輸出原序列 26 printSegment(0, array.length - 1, array); 27 // 求最大子段和 28 int maxSum = maxSum(array); 29 System.out.println("最大字段和:" + maxSum); 30 } 31 32 private static int maxSum(int[] array) { 33 return maxSubSum(array, 1, array.length - 1); 34 } 35 36 private static int maxSubSum(int[] array, int start, int end) { 37 int sum = 0; 38 if (start == end) { 39 sum = array[start] > 0 ? array[end] : 0; 40 } else { 41 int center = (start + end) / 2; 42 // 以n/2為終點(diǎn),往左移動(dòng)擴(kuò)張,求出和最大的一個(gè)startSum 43 int startSum = maxSubSum(array, start, center); 44 // 以n/2+1為起點(diǎn),往右移動(dòng)擴(kuò)張,求出和最大的一個(gè)endSum 45 int endSum = maxSubSum(array, center + 1, end); 46 int s1 = 0; 47 int starts = 0; 48 // 以n/2為終點(diǎn),往左移動(dòng)擴(kuò)張,求出和最大的一個(gè) startSum 49 for (int i = center; i >= start; i--) { 50 starts += array[i]; 51 if (starts > s1) { 52 s1 = starts; 53 } 54 } 55 int s2 = 0; 56 int ends = 0; 57 // 以n/2+1為起點(diǎn),往右移動(dòng)擴(kuò)張,求出和最大的一個(gè) endSum 58 for (int i = center + 1; i <= end; i++) { 59 ends += array[i]; 60 if (ends > s2) { 61 s1 = ends; 62 } 63 } 64 sum = s1 + s2; 65 if (sum < startSum) { 66 sum = startSum; 67 } 68 if (sum < endSum) { 69 sum = endSum; 70 } 71 } 72 return sum; 73 } 74 75 /** 76 * 輸出序列 77 * 78 * @param start:序列的開始下標(biāo) 79 * @param end:序列的結(jié)束下標(biāo) 80 * @param array:要輸出的序列 81 */ 82 private static void printSegment(int start, int end, int[] array) { 83 for (int i = start; i <= end; i++) { 84 System.out.print(array[i] + " "); 85 } 86 System.out.println(); 87 } 88 89 }

4、動(dòng)態(tài)規(guī)劃算法

1 package cn.com.zfc.everyday.test; 2 3 /** 4 * 5 * @title DynamicProgrammingOfMaximumIntervalSum 6 * @describe 最大子段和的動(dòng)態(tài)規(guī)劃算法 7 * @author 張富昌 8 * @date 2017年4月9日下午10:47:00 9 */ 10 public class DynamicProgrammingOfMaximumIntervalSum { 11 public static void main(String[] args) { 12 // 原序列 13 int[] array = { -2, 11, -4, 13, -5, -2 }; 14 System.out.println("原序列是:"); 15 // 輸出原序列 16 printSegment(0, array.length - 1, array); 17 // 求最大子段和 18 int maxSum = maxSum(array); 19 System.out.println("最大字段和:" + maxSum); 20 } 21 22 /** 23 * 24 * @param array:原序列 25 * @return:最大子段和 26 */ 27 private static int maxSum(int[] array) { 28 int sum = 0; 29 int b = 0; 30 for (int i = 0; i < array.length; i++) { 31 if (b > 0) { 32 b += array[i]; 33 } else { 34 b = array[i]; 35 } 36 if (b > sum) { 37 sum = b; 38 } 39 } 40 return sum; 41 } 42 43 /** 44 * 輸出序列 45 * 46 * @param start:序列的開始下標(biāo) 47 * @param end:序列的結(jié)束下標(biāo) 48 * @param array:要輸出的序列 49 */ 50 private static void printSegment(int start, int end, int[] array) { 51 for (int i = start; i <= end; i++) { 52 System.out.print(array[i] + " "); 53 } 54 System.out.println(); 55 } 56 }

轉(zhuǎn)載于:https://www.cnblogs.com/zfc-java/p/6687442.html

總結(jié)

以上是生活随笔為你收集整理的最大子段和问题Java实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。