3.2 分治法

1.分治法是什么?

​ 在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……

​ 通俗的说: 当求解的问题较复杂或规模较大时,不能立刻得到原问题的解,但这些问题本身具有这样的特点,它可以分解为若干个与原问题性质相类似的子问题,而这些子问题较简单可方便得到它们的解,因此通过合并这些子问题的解就可得到原问题的解。

2.应用分治法的三个基本步骤

  • 分解问题(divide):把原问题分解为若干个与原问题性质相类似的子问题
  • 求解子问题(conquer):不断分解子问题直到可方便求出子问题的解为止
  • 合并子问题的解(combine):合并子问题的解得到原问题的解

做题时的三步(与上面类似)

  1. divide:把具有n个元素的数组分解为二个n/2大小的子数组
  2. conquer:递归地分解子数组,直到子数组只包含一个元素为止
  3. combine:二二合并已排好序的子数组使之成为一个新的排好序的子数组,重复这样二二合并的过程直到得到原问题的解

3.案例

3.1二分查找1

在有序数组 { 0, 1, 8, 10, 26, 38, 39, 40 } 中,查找 target 是否存在。

/**
 * 二分法
 * 
 * @author Administrator
 *
 */
public class BinarySearchTest {

	/**
	 * 判断在orderArray这个有序数组中是否存在x
	 * 
	 * @param target
	 * @param orderArray 从小到大
	 */
	private static void binarySearch(int target, int[] orderArray) {
		int middle = 0;
		int low = 0;
		int high = orderArray.length - 1;// 取下标 从0开始

		int tag = 0;
		while (low <= high) {

			middle = (high + low) / 2;
			if (orderArray[middle] == target) {
				tag = 1;
				System.out.println("存在");
				break;
			} else if (orderArray[middle] > target) {
				high = middle - 1;
			} else {
				low = middle + 1;
			}

		}
		if (tag == 0) {
			System.out.println("不存在");
		}

	}

	public static void main(String[] args) {
		int array[] = { 0, 1, 8, 10, 26, 38, 39, 40 };

		binarySearch(30, array);
	}

}

3.1二分查找2

在有序数组 { 0, 1, 8, 10, 26, 38, 39, 40 } 中,查找 第一个大于target的数。

/**
 * 二分法
 * 
 * @author Administrator
 *
 */
public class BinarySearchTest2 {

	/**
	 * 判断在orderArray这个有序数组中 第一个大于target的数
	 * 
	 * @param target
	 * @param arr 从小到大
	 */
	private static int binarySearch(int target, int[] arr) {
		int middle = 0;
		int low = 0;
		int high = arr.length - 1;// 取下标 从0开始

		int tag = -1;
		while (low <= high) {

			middle = (high + low) / 2;

			// 符合条件的情况 n-1<target<n
			if (arr[middle] > target && (middle == 0 || arr[middle - 1] <= target)) {
				tag = arr[middle];
				return tag;
			} else if (arr[middle] > target) {
				high = middle - 1;
			} else {
				low = middle + 1;
			}
		}

		return tag;
	}

	public static void main(String[] args) {
		int array[] = { 0, 1, 8, 10, 26, 38, 39, 40 };

		int tag = binarySearch(39, array);
		if (tag == -1) {
			System.out.println("不存在");
		} else {
			System.out.println("存在:" + tag);
		}
	}

}
posted @ 2020-10-27 17:48  Nixon  阅读(121)  评论(0编辑  收藏  举报