java基础算法学习之分治

这篇文章我们来谈谈分治算法,分治算法也就是将大的问题分解成为小的问题,然后依次求解,如果在一堆硬币里有1个假的硬币,那么我们可以堆硬币为偶数那么分成两堆,然后再质量小的那堆里面求解,如果硬币的个数为奇数,那么我们以中间的为分割,如果两堆相等,那么中间的就是假的,否则就和偶数的求解思路是一样的,然后依次算下去,直到找到假币为止,好吧,贴代码:

package www.jk.divideandconquer;

import java.util.Scanner;

/**
 * 用户可以输入硬币的个数,然后动态输入硬币的质量,只能有一个假币,假币的质量小于真币,然后求出假币的位置
 * 
 * @author jk
 * 
 */
public class Test {
	public static void main(String[] args) {
		int[] coin = new int[1000];
		int number;
		int position;
		System.out.println("输入硬币的数目");
		Scanner input = new Scanner(System.in);
		number = input.nextInt();
		System.out.println("请输入硬币的真假");
		for (int i = 0; i < number; i++) {
			// 得到硬币的质量
			// get the quality of the coin
			coin[i] = input.nextInt();
		}
		// get the position of the false coin
		// 得到假的硬币的位置
		position = falseCoin(coin, 0, number - 1);
		System.out.println("第" + position + "个硬币是假的");

	}

	public static int falseCoin(int[] coin, int low, int high) {
		int res = 0;
		int i, sum1, sum2, sum3;
		sum1 = sum2 = sum3 = 0;
		// if there were only two coin ,the quality of small is false,we need to
		// add 1,because the
		// value we passed in is array subscript
		// 如果只有两个硬币,那么质量小的就是假的,因为是我们传入的是数组的下标,所以位置要加1
		if (low + 1 == high) {
			if (coin[low] < coin[high]) {
				res = low + 1;
			} else {
				res = high + 1;
			}
			return res;
		}
		// if the total number is an even number, then high sub low will get a
		// odd number
		// the number divide 2 is the offset that we want
		// 如果是偶数,想想一下只有两个数,那么high-low得到的是一个奇数,而除以2的结果正好是我们需要的偏移量
		if ((high - low + 1) % 2 == 0) {
			// the sum of firt half
			// 前半段的和
			for (i = low; i <= low + (high - low) / 2; i++) {
				sum1 += coin[i];
			}
			// the sum of last half
			// 后半段的和
			for (i = low + (high - low) / 2 + 1; i <= high; i++) {
				sum2 += coin[i];
			}
			// if the sum1>sum2,the false coin is in the rear
			// 如果前面大,那么假币在后面
			if (sum1 > sum2) {
				res = falseCoin(coin, low + (high - low) / 2, high);
			} else {
				// else the false coin is in the begin
				// 否则的话,假币在前面
				res = falseCoin(coin, low, low + (high - low) / 2);
			}
			// return the result
			// 返回得到的结果
			return res;

		} else {
			// if the number is odd, we can image that the total number is
			// threee ,and high-low will get a evev number
			// this number will bigger one than the offset that we need
			// 如果是奇数,我们可以想象为3,那么high-low得到的是一个偶数,而除以2以后得到的数
			// 比我们需要的偏移量多1个,那么我们前半段需要减1,后半段需要加1
			// the sum of begin half
			// 前半段的和
			for (i = low; i <= low + (high - low) / 2 - 1; i++) {
				sum1 += coin[i];
			}
			// the sum of end hald
			// 后半段的和
			for (i = low + (high - low) / 2 + 1; i <= high; i++) {
				sum2 += coin[i];
			}
			// if sum1 is bigger ,the false coin is in the rear
			// 如果前半段大,那么假币在后半段
			if (sum1 > sum2) {
				res = falseCoin(coin, low + (high - low) / 2, high);
			} else if (sum2 > sum1) {
				// if sum2 is bigger, the false coin is in the begin
				// 如果后半段大,那么假币在前半段
				res = falseCoin(coin, low, low + (high - low) / 2);
			} else {
				// then the result is in the middle
				// 否则结果就在中间
				res = low + (high - low) / 2 + 1;
			}
			return res;

		}

	}

}


你可能感兴趣的:(java基础算法)