K:找寻最长子序列的四个算法

该博客展示了寻找最长子序列的四种不同算法,包括O(N^3)、O(N^2)、O(NlogN)和O(N)的时间复杂度解决方案。作者通过Java代码详细解释了每种算法的思路和实现,适用于理解不同复杂度的求解策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package other;
/**
 * 该类用于演示寻找最长子序列的几种算法
 * @author 学徒
 *
 */
public class MaxSubLined
{
	public static void main(String[] args)
	{
		int[] array={-2,11,-4,13,-5,2,-5,-3,12,-9};
		MaxSubLined max=new MaxSubLined();
		System.out.println(max.maxSubN3(array));
		System.out.println(max.maxSubN2(array));
		System.out.println(max.maxSubNlogN(array));
		System.out.println(max.maxSubN(array));
	}
	/**
	 * 用于演示O(N^3)的算法
	 * 算法的思路:
	 * 穷举数组中以某个元素为起始的,数组中以该元素为起始元素的所有子序列的可能
	 * 并找出其中子序列和最大的那个值
	 * @param array 用于寻找最长子序列的数组
	 * @return 最长子序列的值
	 */
	public int maxSubN3(int[] array)
	{
		int result=0;
		int length=array.length;
		//用于控制子序列的起始下标
		for(int i=0;i<length;i++)
		{
			//用于控制子序列的终止下标
			for(int j=i;j<length;j++)
			{
				//用于计算起始下标到终止下标之间的元素的和
				int sum=0;
				for(int k=i;k<=j;k++)
				{
					sum+=array[k];
				}
				result=Math.max(sum, result);
			}
		}
		return result;
	}
	/**
	 * 用于演示O(N^2)的算法
	 * 算法的思路:
	 * 穷举数组中以某个元素为起始的,数组中以该元素为起始元素的所有子序列的可能
	 * 并找出其中子序列和最大的那个值
	 * @param array 用于寻找最长子序列的数组
	 * @return 最长子序列的值
	 */
	public int maxSubN2(int[] array)
	{
		int length=array.length;
		int result=0;
		for(int i=0;i<length;i++)
		{
			int sum=0;
			for(int j=i;j<length;j++)
			{
				sum+=array[j];
				result=Math.max(result, sum);
			}
		}
		return result;
	}
	/**
	 * 用于演示O(NlogN)的算法
	 * 算法的思路:
	 * 采用分治的思想,将数组划分为两半,最长子序列出现的可能只有三种
	 * 要么在数组的左半边,要么在数组的右半边,要么横跨了数组的左右半边,同时其必定包含
	 * 数组左半边的右边界以及数组右半边的左边界
	 * @param array 用于寻找最长子序列的数组
	 * @return
	 */
	public int maxSubNlogN(int[] array)
	{
		return maxSubNlogN(array,0,array.length-1);
	}
	/**
	 * 用于递归的那个方法,low和high为数组的左右边界
	 */
	private int maxSubNlogN(int[] array,int low,int high)
	{
		//当只剩下一个数组元素的时候,将其直接进行返回
		if(low==high)
			return Math.max(array[low], 0);
		//找到数组中间的分界点
		int mid=low+(high-low)/2;
		//用于寻找到横跨数组左右半边的那个最长子序列
		int lMax=0,rMax=0;
		int lSum=0,rSum=0;
		//找到包含右边界的左半边的最长子序列
		for(int i=mid;i>=low;i--)
		{
			lSum+=array[i];
			lMax=Math.max(lSum, lMax);
		}		
		//找到包含左边界的右半边的最长子序列
		for(int i=mid+1;i<high;i++)
		{
			rSum+=array[i];
			rMax=Math.max(rSum, rMax);
		}
		//返回三种情况中子序列和最大的那个值
		return Math.max(maxSubNlogN(array,mid+1,high),Math.max(rMax+lMax, maxSubNlogN(array,low,mid)));
	}
	/**
	 * 用于演示O(N)的算法
	 * 算法的思路:
	 * 因为最长子序列中的任意一个子序列里的元素值总和均为正数
	 * 为此,可以在遍历数组的过程中,计算出其最长子序列
	 * @param array 用于寻找最长子序列的数组
	 * @return 最长子序列的值
	 */
	public int maxSubN(int[] array)
	{
		int sum=0;
		int result=0;
		for(int i=0;i<array.length;i++)
		{
			sum+=array[i];
			if(sum>result)
				result=sum;
			if(sum<0)
				sum=0; 
		}
		return result;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值