package code_08_chapter;
/*
*Created by William on 2018/6/22 0022
*/
public class QuestionsInChapter8 {
/**
* 给定一个含有n个元素的vector,找出其中最大的子向量(即所有元素之和为最大值)。
* 如果是都为正数,那么问题变得十分简单,整个vector即是最大子向量,但是如果是正数负数混合的形式呢?
* 问题将变得复杂,接下来将简要介绍几种算法的思路。其复杂度由最初的立方算法降低到最终的线性算法!
* (提供的代码细节处如数据类型例如int之类自己根据情况填加)
*/
//立方算法,思想很简单,即遍历所有情况:
public static int cubicAlgorithm(int[] array) {
int maxfactor = 0;
int sum;
int length = array.length;
for (int i = 0; i < length; i++) {
for (int j = i; j < length; j++) {
sum = 0;
for (int k = i; k < j; k++) {
sum += array[k];
}
maxfactor = Math.max(maxfactor, sum);
}
}
return maxfactor;
}
//其实不必每有一个[i,j]便重新求和一次,可以在遍历的过程中进行求和,因此,可以降低算法的复杂度为平方算法:Square algorithm
public static int squareAlgorithm(int[] array) {
int maxfactor = 0;
int length = array.length;
int sum;
for (int i = 0; i < length; i++) {
sum = 0;
for (int j = i; j < length; j++) {
sum += array[j];
maxfactor = Math.max(maxfactor, sum);
}
}
return maxfactor;
}
//使用常见的分治算法又可以进一步的降低算法的复杂度O(nlogn):Divide and conquer algorithm
public static int divideAndConquerAlgorithm(int l, int u, int[] array) {
if (l > u) return 0; // zero elements
if (l == u) return Math.max(0, array[l]); //one element
int sum;
int m = (l + u) / 2;
// find max crossing to left
int leftMax;
leftMax = sum = 0;
for (int i = m; i >= l; i--) {
sum += array[i];
leftMax = Math.max(leftMax, sum);
}
// find max crossing to right
int rightMax;
rightMax = sum = 0;
for (int q = m + 1; q <= u; q++) {
sum += array[q];
rightMax = Math.max(rightMax, sum);
}
return tripleMax(leftMax + rightMax, divideAndConquerAlgorithm(l, m, array), divideAndConquerAlgorithm(m + 1, u, array));
}
public static int tripleMax(int a, int b, int c) {
int temp = Math.max(a, b);
return Math.max(temp, c);
}
//扫描算法,思路借鉴分治算法,不过使复杂度达到最低O(n),即线性算法:
public static int scanningAlgorithm(int[] arr){
int maxSoFar = 0;
int maxEndingHere = 0;
int n = arr.length;
for(int i =0; i< n; i++){
maxEndingHere = Math.max(maxEndingHere+arr[i],0);
maxSoFar = Math.max(maxSoFar,maxEndingHere);
}
return maxSoFar;
}
public static void main(String[] args) {
int[] arr = new int[]{31, -41, 59, 26, -53, 58, 97, -93, -23, 84};
System.out.println(cubicAlgorithm(arr));
System.out.println(squareAlgorithm(arr));
System.out.println(divideAndConquerAlgorithm(0, arr.length - 1, arr));
System.out.println(scanningAlgorithm(arr));
}
}
算法------编程珠玑(ProgrammingPeals)第八章(JAVA)
最新推荐文章于 2022-05-13 17:23:38 发布