《算法导论(第三版)》第四章 分治策略 第1节 提到的一些算法

《算法导论(第三版)》第四章 分治策略 第1节 提到的一些算法


《算法导论(第三版)》第四章 分治策略 第1节 提到的最大子数组求解算法。包含了分治策略算法、暴力求解算法、根据求解规模分别调用分治策略算法,暴力求解算法、以及出现空集情况的实现。

/**
 * 《算法导论(第三版)》第四章 分治策略 第1节 提到的一些算法
 **/
public class Alg_04_01{
	public static void main(String[] args) {
		Alg_04_01_1.mehtod();
		Alg_04_01_2.mehtod();
		Alg_04_01_3.mehtod();
		Alg_04_01_4.mehtod();
		Alg_04_01_5.mehtod();
	}
}
/**
 * 《算法导论(第三版)》第四章 分治策略 第1节 提到最大子数组的分治策略算法
 ***/

class Alg_04_01_1{
	public static void mehtod() {
		System.out.println("《算法导论(第三版)》第四章 分治策略 第1节 提到最大子数组的分治策略算法Alg_04_01_1.mehtod:");
		int[] arr=new int[]{13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
		int[] ret=alg(arr, 0, arr.length-1);
		for(int i=0;i<ret.length;i++) {
			System.out.print(ret[i]+",");
		}
		System.out.println();
		System.out.println("《算法导论(第三版)》第四章 分治策略 第1节 提到最大子数组的分治策略算法(全部为负数的情况)Alg_04_01_1.mehtod:");
		arr=new int[]{-1,-3,-25,-1,-3,-16,-23,-1,-1,-7,-1,-5,-22,-1,-4,-7};
		ret=alg(arr, 0, arr.length-1);
		for(int i=0;i<ret.length;i++) {
			System.out.print(ret[i]+",");
		}
		System.out.println();
	}
	/**
	 * @return [0]-low,[1]-high,sum-[2]
	 * */
	public static int[] alg(int[] arr,int low,int high) {
		if(low==high) {
			return new int[] {low,low,arr[low]};
		}else {
			int mid=(low+high)/2;
			int[] lret=alg(arr,low,mid);			
			int[] rret=alg(arr,mid+1,high);
			int[] mret=alg1(arr,low,mid ,high);
			if(lret[2]>rret[2]&&lret[2]>mret[2]) {
				return lret;
			}else {
				if(rret[2]>mret[2]) {
					return rret;
				}else {
					return mret;
				}
			}
		}
		
	}
	/**
	 * @return [0]-low,[1]-high,sum-[2]
	 * */
	public static int[]alg1(int[] arr,int low,int mid,int high){
		int left_sum=arr[mid];
		int max_left=mid;
		int sum=0;
		
		for(int i=mid;i>=low;i--) {
			sum+=arr[i];
			if(sum>=left_sum) {
				left_sum=sum;
				max_left=i;
				
			}
		}
		
		int right_sum=arr[mid+1];
		int max_right=mid+1;
		sum=0;
		for(int i=mid+1;i<=high;i++) {
			sum+=arr[i];
			if(sum>=right_sum) {
				right_sum=sum;
				max_right=i;
			}
		}
		return new int[]{max_left,max_right,left_sum+right_sum};
		
	}
}
/**
 * 《算法导论(第三版)》第四章 分治策略 第1节 练习题4.1-2 提到最大子数组的 暴力求解算法
 ***/
class Alg_04_01_2{
	public static void mehtod() {
		System.out.println("《算法导论(第三版)》第四章 分治策略 第1节 练习题4.1-2 提到最大子数组的 暴力求解算法Alg_04_01_2.mehtod:");
		int[] arr=new int[]{13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
		int[] ret=alg(arr);
		for(int i=0;i<ret.length;i++) {
			System.out.print(ret[i]+",");
		}
		System.out.println();
	}
	public static int[] alg(int[] arr) {
		int[] ret=new int[] {0,0,arr[0]};
		for(int i=0;i<arr.length;i++) {
			int sum=0;
			for(int j=i;j<arr.length;j++) {
				sum+=arr[j];
				if(sum>ret[2]) {
					ret[0]=i;
					ret[1]=j;
					ret[2]=sum;
				}
			}
		}
		return ret;
	}
}
/**
 * 《算法导论(第三版)》第四章 分治策略 第1节 练习题4.1-3 提到最大子数组的 根据性能交叉点分别调用暴力求解法和分治策略算法<br>
 * 分治策略算法复杂度为t=(n+1)*log(2,n)<br>
 * 暴力求解算法复杂度为t=(n+1)*n/2<br>
 * 令n=1,2,2^2,2^3,2^4<br>
 * 得到分治策略算法时间为t=1,3,10,24,68<br>
 * 得到暴力求解算法时间为t=1,3,10,36,136<br>
 * 性能交叉点在[2^3~2^4]。
 ***/
class Alg_04_01_3{

	public static void mehtod() {
		System.out.println("《算法导论(第三版)》第四章 分治策略 第1节 练习题4.1-3 提到最大子数组的 根据性能交叉点分别调用暴力求解法和分治策略算法Alg_04_01_3.mehtod:");
		int[] arr=new int[]{13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
		int[] ret=alg(arr, 0, arr.length-1);
		for(int i=0;i<ret.length;i++) {
			System.out.print(ret[i]+",");
		}
		System.out.println();
	}
	/**
	 * @return [0]-low,[1]-high,sum-[2]
	 * */
	public static int[] alg(int[] arr,int low,int high) {
		if(high-low<=8) {
			int[] ret=new int[] {low,low,arr[low]};
			for(int i=low;i<=high;i++) {
				int sum=0;
				for(int j=i;j<=high;j++) {
					sum+=arr[j];
					if(sum>ret[2]) {
						ret[0]=i;
						ret[1]=j;
						ret[2]=sum;
					}
				}
			}
			return ret;
		}else {
			int mid=(low+high)/2;
			int[] lret=alg(arr,low,mid);			
			int[] rret=alg(arr,mid+1,high);
			int[] mret=Alg_04_01_1.alg1(arr,low,mid ,high);
			if(lret[2]>rret[2]&&lret[2]>mret[2]) {
				return lret;
			}else {
				if(rret[2]>mret[2]) {
					return rret;
				}else {
					return mret;
				}
			}
		}
		
	}
}
/**
 * 《算法导论(第三版)》第四章 分治策略 第1节 练习题4.1-4 假定修改最大子数组的问题的定义,允许结果为空子数组,其和为0。你应该如何修改现有的算法,使他们能允许空子数组的为最终结果?<br>
 * 可在数组末尾加入元素0。当返回的起止下标均为元素0的下标时时,则为空集。
 ***/
class Alg_04_01_4{

	public static void mehtod() {
		System.out.println("《算法导论(第三版)》第四章 分治策略 第1节 练习题4.1-4 允许返回空集的情况Alg_04_01_4.mehtod");
		int[] arr=new int[]{13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7,0};//数组末尾加入了0
		int[] ret=Alg_04_01_1.alg(arr, 0, arr.length-1);
		if(ret[0]==arr.length-1&&ret[1]==arr.length-1) {
			System.out.print("空集");
		}else {
			for(int i=0;i<ret.length;i++) {
				System.out.print(ret[i]+",");
			}	
		}
		
		System.out.println();
		System.out.println("《算法导论(第三版)》第四章 分治策略 第1节 练习题4.1-4 允许返回空集的情况Alg_04_01_4.mehtod");
		arr=new int[]{-1,-3,-25,-1,-3,-16,-23,-1,-1,-7,-1,-5,-22,-1,-4,-7,0};//数组末尾加入了0
		ret=Alg_04_01_1.alg(arr, 0, arr.length-1);
		//ret=Alg_04_01_2.alg(arr);
		ret=Alg_04_01_3.alg(arr, 0, arr.length-1);
		if(ret[0]==arr.length-1&&ret[1]==arr.length-1) {
			System.out.print("空集");
		}else {
			for(int i=0;i<ret.length;i++) {
				System.out.print(ret[i]+",");
			}
		}
		System.out.println();
	}
}
/**
 * 《算法导论(第三版)》第四章 分治策略 第1节 练习题4.1-5 已知A【1,j】的最大子数组,求A【1,j+1】的最大子数组要求算法在线性时间范围内。<br>
 * 暴力求解算法Alg_04_01_2是这个思想
 * 
 ***/
class Alg_04_01_5{

	public static void mehtod() {
		System.out.println("《算法导论(第三版)》第四章 分治策略 第1节 练习题4.1-5 已知A【1,j】的最大子数组,求A【1,j+1】的最大子数组Alg_04_01_5.mehtod:");
		int[] arr=new int[]{13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
		int[] ret=alg(arr);
		for(int i=0;i<ret.length;i++) {
			System.out.print(ret[i]+",");
		}
		
	}
	public static int[] alg(int[] arr) {
		int[] ret=new int[] {0,0,arr[0]};
		for(int i=0;i<arr.length;i++) {
			if(i>0) {
				System.out.println("已知a[0,"+(i-1)+"]的最大子数组为a["+ret[0]+","+ret[1]+"]");
			}
			
			int sum=0;
			for(int j=i;j>=0;j--) {
				sum+=arr[j];
				if(sum>ret[2]) {
					ret[0]=j;
					ret[1]=i;
					ret[2]=sum;
				}
			}
			System.out.println("求得a[0,"+i+"]的最大子数组为a["+ret[0]+","+ret[1]+"]");
		}
		return ret;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值