求一个数组中最大的相邻元素之和
2011-03-07 15:05
357 查看
本文来自CSDN博客:http://blog.csdn.net/gaoyusi4964238/archive/2010/05/18/5605123.aspx
问题描述:
给定一个数据,求数据中相邻元素的最大和。例如:对于数组[5,-6,5,3,6,-8],其相邻元素最大和为14(5+3+6)。
算法实现如下:
view plaincopy to clipboardprint?
package test;
import java.util.Random;
import org.junit.Test;
public class TestAlgorithm {
/**
* 对于数组分为两个大小基本相等的部分,那么最大和集必然出现在以下三种情况下:
* <p>1.最大和集出现在前半部分内,或者是整个前半部分;
* <p>2.最大和集出现在后半部分内,或者是整个后半部分;
* <p>3.如果过既不出现在前半部分,也不出现在后半部分,那么最大和必然横跨前半部分和后半部分,
* 所以前半部分(假设a)和后半部分(假设b)的分割点(假设i)必然包含在最大和集中,那么这时候只需要以i
* 为起点向前求其最大和集(c1),向后求其最大和集(c2),那么这种情况下最大和集为c1+c2;
* <p>所以最大和集的求法即可采用分治算法,递归求出数组前半部分,后半部分,和整个部分的最大值即可。
*/
public int divideAndConquerSum(int[] a,int low,int high){
if(low>high)
return 0;
if(low==high)
return max(0,a[low]);
//求出在[low,high]内包含a[mid]的最大sum
int mid=(low+high)/2;
int isum=0;
int lsum=0;
int rsum=0;
for(int i=mid;i>=low;i--){
isum+=a[i];
lsum=max(isum,lsum);
}
isum=0;
for(int i=mid+1;i<=high;i++){
isum+=a[i];
rsum=max(isum,rsum);
}
return max(lsum+rsum,divideAndConquerSum(a,low,mid),divideAndConquerSum(a,mid+1,high));
}
/**
* 扫描算法
*/
public int scanningSum(int[] a){
int sum=0;
int tmpSum=0;
for(int i=0;i<a.length;i++){
//如果前i位之和为负数,那么说明前i位不可能包含在最大和集中,重置tmpSum
tmpSum=max(tmpSum+a[i],0);
sum=max(tmpSum,sum);
}
return sum;
}
public int max(int a,int b){
return a>b?a:b;
}
public int max(int a,int b,int c){
//System.out.println("a:"+a+";b:"+b+";c:"+c);
return max(a,max(b,c));
}
@Test
public void test(){
Random random=new Random();
int [] a=new int[random.nextInt(10)];
for(int i=0;i<a.length;i++){
a[i]=random.nextInt(100)-random.nextInt(100);
System.out.print(a[i]+",");
}
System.out.println("数组长度:"+a.length);
int dMax=divideAndConquerSum(a,0,a.length-1);
System.out.println("分治算法:"+dMax);
int sMax=scanningSum(a);
System.out.println("扫描算法:"+dMax);
}
}
问题描述:
给定一个数据,求数据中相邻元素的最大和。例如:对于数组[5,-6,5,3,6,-8],其相邻元素最大和为14(5+3+6)。
算法实现如下:
view plaincopy to clipboardprint?
package test;
import java.util.Random;
import org.junit.Test;
public class TestAlgorithm {
/**
* 对于数组分为两个大小基本相等的部分,那么最大和集必然出现在以下三种情况下:
* <p>1.最大和集出现在前半部分内,或者是整个前半部分;
* <p>2.最大和集出现在后半部分内,或者是整个后半部分;
* <p>3.如果过既不出现在前半部分,也不出现在后半部分,那么最大和必然横跨前半部分和后半部分,
* 所以前半部分(假设a)和后半部分(假设b)的分割点(假设i)必然包含在最大和集中,那么这时候只需要以i
* 为起点向前求其最大和集(c1),向后求其最大和集(c2),那么这种情况下最大和集为c1+c2;
* <p>所以最大和集的求法即可采用分治算法,递归求出数组前半部分,后半部分,和整个部分的最大值即可。
*/
public int divideAndConquerSum(int[] a,int low,int high){
if(low>high)
return 0;
if(low==high)
return max(0,a[low]);
//求出在[low,high]内包含a[mid]的最大sum
int mid=(low+high)/2;
int isum=0;
int lsum=0;
int rsum=0;
for(int i=mid;i>=low;i--){
isum+=a[i];
lsum=max(isum,lsum);
}
isum=0;
for(int i=mid+1;i<=high;i++){
isum+=a[i];
rsum=max(isum,rsum);
}
return max(lsum+rsum,divideAndConquerSum(a,low,mid),divideAndConquerSum(a,mid+1,high));
}
/**
* 扫描算法
*/
public int scanningSum(int[] a){
int sum=0;
int tmpSum=0;
for(int i=0;i<a.length;i++){
//如果前i位之和为负数,那么说明前i位不可能包含在最大和集中,重置tmpSum
tmpSum=max(tmpSum+a[i],0);
sum=max(tmpSum,sum);
}
return sum;
}
public int max(int a,int b){
return a>b?a:b;
}
public int max(int a,int b,int c){
//System.out.println("a:"+a+";b:"+b+";c:"+c);
return max(a,max(b,c));
}
@Test
public void test(){
Random random=new Random();
int [] a=new int[random.nextInt(10)];
for(int i=0;i<a.length;i++){
a[i]=random.nextInt(100)-random.nextInt(100);
System.out.print(a[i]+",");
}
System.out.println("数组长度:"+a.length);
int dMax=divideAndConquerSum(a,0,a.length-1);
System.out.println("分治算法:"+dMax);
int sMax=scanningSum(a);
System.out.println("扫描算法:"+dMax);
}
}
相关文章推荐
- 给定一个非负数组,求不相邻元素的最大和。
- php 求一个无序数组经过排列后任意两个相邻元素之差的最大值(算法)
- 一个无序实数数组中的相邻两个元素的最大差值
- 求一个非负整数数组中不相邻元素之和的最大值
- 给一个整数数组,有正有负。找出数组最大和,条件是使用的元素不能有相邻
- 算法习题45:对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一;;;一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 求2维数组相邻元素的和的最大值
- 同时寻找一个数组中的最大元素和最小元素--你会有所收获
- [LeetCode] House Robber II 求循环数组中元素两两不相邻的子序列最大和
- java找出一个数组中出现次数最多且最大的那个元素
- 要求一个数组连续下标和的最大值,数组的元素可正、可负、可为零
- 10.2 设计一个函数模板 max <T>求一个数组中最大的元素,并以整数数组和字符数 组进行调用
- 在一个无序数组中找到第K个最小或者最大的元素
- 输入一个一维数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
- 编写一个C#程序,要求从键盘输入10个数存放在数组中,分别求出最大数和最小数存放在第一第二个元素里
- 编写一个通用程序,将二维数组含有最大元素的列与第0列元素对调。例如,原数组和调换后的目标数组为
- 华为:给定一个数组input[],如果数组长度n为奇数,则将数组中最大的元素放到 output[]数组最中间的位置,如果数组长度n为偶数。。
- 无序数组O(n)时间找到排序后的两个相邻元素使得他们之间的差最大
- 数组中不相邻元素的最大和
- 数组最大相邻元素之和