【数据结构】求解PTA最大子列和问题的三种方法(Java版)

import java.util.Scanner;

class Maximum_Subsequence_Sum {
	
	/**
	 * 优化穷举法求最大子序列和   O(n^2)
	 * @param a
	 * @param size
	 * @return
	 */
	public static int max_sub(int[] a, int size)			
	{
		int i, j, v;
		int max = a[0];
		for (i = 0; imax)  max = v;
			}
		}
		return max;
	}
	
	/**
	 * 分治法求最大子序列和//O(NlogN)
	 * @param A
	 * @param left
	 * @param right
	 * @return
	 */
	public static int MaxSubSeqSum(int[] A, int left, int right)
	{
		//左右两边各自的分治算法最大子序列和(递归调用)
		int MaxLeftSum, MaxRightSum, MaxSum;
		//中间位置左右两边各自的最大边界和
		int MaxLeftBorderSum, MaxRightBorderSum;
		//递归过程中左右两边各自的子序列和
		int LeftBorderSum, RightBorderSum;
		int center;
		int i;
		
		if (left == right)
		{
			if (A[left] > 0)
				return A[left];
			else
				return 0;
		}
	 
		center = (left + right) / 2;
	 
		MaxLeftSum = MaxSubSeqSum(A, left, center);
		MaxRightSum = MaxSubSeqSum(A, center + 1, right);
	 
		MaxLeftBorderSum = 0;
		LeftBorderSum = 0;
	 
		for (i = center; i >= left; i--)
		{
			LeftBorderSum += A[i];
			if (LeftBorderSum > MaxLeftBorderSum)
				MaxLeftBorderSum = LeftBorderSum;
		}
	 
	 
		MaxRightBorderSum = 0;
		RightBorderSum = 0;
		for (i = center + 1; i <= right; i++)
		{
			RightBorderSum += A[i];
			if (RightBorderSum > MaxRightBorderSum)
				MaxRightBorderSum = RightBorderSum;
		}
	 
		//比较左右两边各自的分治算法最大子序列和(递归调用)以及中间位置左右两边各自的最大边界和这三者之间的大小
		MaxSum = Max_3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);
	 
		return MaxSum;
	 
	}
	
	static int Max_3(int a, int b, int c)     
	{
		if (a < b)
			a = b;
		if (a < c)
			return c;
		else
			return a;
	}

	/**
	 * 动态规划法(在线算法)求最大子序列和    //O(n)
	 * @param a
	 * @param size
	 * @return
	 */
	public static int max_dg(int[] a)			
	{
		int start=0, finish = 0;
		int maxsum = 0;
		int temp_sum = 0;
		int flag = 0; 
	
		//数组中含有正数
		for (int i = 0,j=0; j maxsum)
			{
				maxsum = temp_sum; 
				start=i+1;
				finish = j+1;
			}
			else if (temp_sum<0){
				temp_sum = 0;
				i=j+1;
			}
		}
		
		//在该循环内判断序列中是否存在正数   	
		for (int i = 0; i0) flag = 1;      //用flag标记,若存在正数则为1   
		
		//若不存在正数,则输出0和首尾元素
		if (flag == 0)             	   
		{   
			maxsum = 0; start = 1; finish = a.length;
			return 0;
		}
	 
		System.out.println("首尾项下标分别为:" +start+" "+finish);
		return maxsum; 
	}

	/**
	 * 测试函数
	 * @param args
	 */
	public static void main(String[] args) {
		int i,j;
		int[] a=new int[10];
		Scanner in=new  Scanner(System.in);
		//输入序列的长度
		System.out.println("please input a number");
		j=in.nextInt();
		//输入序列
		System.out.println("please input the numbers");
		for(i=0;i < j; i++){
			a[i]=in.nextInt();
		}
		System.out.println("the number row is:");
		for(i = 0; i < j; i++){
			System.out.print(a[i]+" ");
		}	
		
		System.out.println("The sum of biggest row is:"+max_sub(a,j));
	}
}


 

 

 

你可能感兴趣的:(算法,数据结构)