input:待搜索目标整数,目标数组
output:找到目标整数的索引,找不到则 -1
Constraints: 目标数组有序排列 ,升降序
二分法搜索思想:
举例说明:
你是个摸牌高手,不用掀开麻将只需用手摸就能摸出牌面,桌面扣着80个麻将牌,不同的是麻将上刻的是80个1到500的升序不连续数字,
形如: 2,3,6,12,13,15….. 为了证明你确实是个高手,你还被蒙上了眼睛,那你怎么向众人秀你的超能力呢
观众要求你快速的找到 大家说出的数字,二分法浮上你的心头….
超能力过程:
你需要一个助手在你蒙眼情况下,
(A)帮助你把手按在桌上剩余牌数中间的那张牌上,你用手摸看是否要找的牌,是则结束了
(B)不是,那么,如果如果摸起来的牌小于 要找的牌 ,说明 目标牌 一定位于 80张牌拦腰分开 的后半部分, 前半部分牌可以扔掉了
继续,助手帮你拦腰截断桌面剩下的牌,你 重复(A)
结束条件:最终待搜索数组只有一个元素 ,不是要搜索的元素则没找到
先贴上我的Ugly递归方式
注意一点,最终搜索到元素的索引是分半后新数组的,所以需要记录在原数组中的索引,这是我的这个递归方式的丑陋之处,先放着,怎么想的就怎么记录,像当时写五子连珠寻路时也是用了一个递归,结果在android机器上总内存溢出,后来同事一句话惊醒我,A*才是正途,基本功不扎实导致思考问题的方式,方向不对,数学真的是计算机的灵魂
package org.algorithm;
/**
*
* @author Administrator
*
*/
public class HalfSearch {
private static int[] arr = { 1, 2, 3, 4, 5, 6, 9, 10 };
/**
* 二分查找使用递归方法后,找到的索引是新数组的 需要记录原有位置索引
*/
private static int indexBasic = 0;
/**
* 二分搜索(递归方式) input:目标元素 ,目标数组 output:目标元素是否存在于该数组,存在则返回索引
* constraint:目标数组有序排列
*
* @param seachTarget
* @param arr_input
* @return -1 not found
*/
private static int halfSearch(int searchTarget, int[] arr_input) {
/**
* 长度为一的数组,直接搜索,也作为递归的终点 当二分到最终变成只有一个元素的数组时,可以确定是否找到
*/
if (arr_input.length == 1) {
if (arr_input[0] == searchTarget) {
return indexBasic + 0;
} else {
return -1;
}
}
/**
* 把数组拦腰折断,检查折断点是否是要找的元素
*/
int curIndex = arr_input.length / 2;
// found !
if (arr_input[curIndex] == searchTarget) {
return indexBasic + curIndex;
} else {
/**
* 折断点元素 小于要查找元素 说明要找的元素不会存在于前半段了
*/
if (arr_input[curIndex] < searchTarget) {
/**
* 后半段搜索 找到的索引需要累加基数index
*/
int[] newarr_input = new int[arr_input.length - curIndex - 1];
System.arraycopy(arr_input, curIndex + 1, newarr_input, 0,
newarr_input.length);
indexBasic += curIndex + 1;
return halfSearch(searchTarget, newarr_input);
} else {
int[] newarr_input = new int[curIndex];
System.arraycopy(arr_input, 0, newarr_input, 0, curIndex);
return halfSearch(searchTarget, newarr_input);
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
indexBasic = 0;
long start = System.currentTimeMillis();
System.out.println("搜索9,结果索引:" + halfSearch(9, arr));
long end = System.currentTimeMillis();
System.out.println("time used:" + (end - start));
}
}