标签:
分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。
当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治的基本思想。
1 package com.chenjun.packge1; 2 3 public class Algorithm { 4 private static int a[] = new int[10]; 5 static{ 6 for(int i=0;i<a.length;i++){ 7 a[i] = 100; 8 } 9 a[3] = 88; //a[3] is false 10 } 11 public static void main(String[] args) { 12 for(int i=0;i<a.length;i++){ 13 System.out.print(" "+"a["+i+"] ="+a[i]); 14 } 15 System.out.println("\n"); 16 int number; 17 number = falseCoin(a,0,a.length-1); //a0~a9 18 System.out.println("找到了! 假币的数组下标是:"+number); 19 } 20 /** 21 * @param int []a,int beginIndex,int endIndex 22 * @param beginIndex: 起始点数组下标 23 * @param endIndex: 终止点数组下标 24 * @return 返回编号 25 */ 26 public static int falseCoin(int []a,int beginIndex,int endIndex){ 27 if(beginIndex + 1 == endIndex){ //如果只剩下最好两枚硬币 28 if(a[beginIndex] > a[endIndex]){ 29 return endIndex; 30 } 31 else{ 32 return beginIndex; 33 } 34 } 35 if((endIndex - beginIndex +1)%2 == 0 ){ //区间个数为偶数 36 int sum1 = 0; 37 int sum2 = 0; 38 for(int i = beginIndex ; i < (beginIndex+endIndex)/2+1; i++){ 39 sum1 = sum1+a[i]; //前半段 40 } 41 for(int j = (beginIndex +endIndex)/2+1; j < endIndex+1; j++){ 42 sum2 = sum2 + a[j]; // 后半段 43 } 44 if(sum1 < sum2){ //假币在左侧 45 System.out.print("假币藏在这其中之一 : "); 46 for(int i = beginIndex ; i < (beginIndex+endIndex)/2+1; i++){ 47 System.out.print(i+","); 48 } 49 System.out.println("\n"); 50 return falseCoin(a,beginIndex,(beginIndex+endIndex)/2); //开始数~中间数向下取整 51 } 52 if(sum1 > sum2){ //假币在右侧s 53 System.out.print("假币藏在这其中之一 : "); 54 for(int j = (beginIndex +endIndex)/2+1; j < endIndex+1; j++){ 55 System.out.print(j+","); 56 } 57 System.out.println("\n"); 58 return falseCoin(a,(beginIndex+endIndex)/2+1,endIndex); //中间数向下取整+1~尾数 59 } 60 } 61 if((endIndex - beginIndex +1)%2 == 1){ //区间个数为奇数(01 | 2 | 34) i=0 62 int sum3 = 0; 63 int sum4 = 0; 64 for(int i=beginIndex;i<(beginIndex+endIndex)/2;i++){ //左半段 65 sum3 = sum3+a[i]; 66 } 67 for(int j=(beginIndex+endIndex)/2+1; j< endIndex+1; j++){ 68 sum4 = sum4+a[j]; 69 } 70 if(sum3<sum4){ 71 System.out.print("假币藏在这其中之一 : "); 72 for(int i=beginIndex;i<(beginIndex+endIndex)/2;i++){ //左半段 73 System.out.println(i+","); 74 } 75 System.out.println("\n"); 76 return falseCoin(a,beginIndex,(beginIndex+endIndex)/2-1); 77 } 78 if(sum3>sum4){ 79 System.out.print("假币藏在这其中之一 : "); 80 for(int j=(beginIndex+endIndex)/2+1; j< endIndex+1; j++){ 81 System.out.print(j+","); 82 } 83 System.out.println("\n"); 84 return falseCoin(a,(beginIndex+endIndex)/2+1,endIndex); 85 } 86 if(sum3 == sum4){ 87 return (beginIndex+endIndex)/2; //中间者是假币,函数立即返回 88 } 89 } 90 return -1; //不存在假币 91 } 92 }
运行结果:
a[0] =100 a[1] =100 a[2] =100 a[3] =88 a[4] =100 a[5] =100 a[6] =100 a[7] =100 a[8] =100 a[9] =100
假币藏在这其中之一 : 0,1,2,3,4,
假币藏在这其中之一 : 3,4,
找到了! 假币的数组下标是:3
标签:
原文地址:http://www.cnblogs.com/ChenJunHacker/p/4437470.html