二分法,二分法,简单来说就是将一个问题拆成二半,分成几个比较小的问题,在数据量以及计算次数比较多时候就能极大限度减少时间复杂度。
现在我们要处理一个这样的问题,比如我们算出某种数据的规律,要将一堆数据的走势算出来,为了不是很枯燥,咱就弄个好玩的例子吧,
例如你获得了个神器的瓶子,你可以每天向它要钱,它可能给你一定数量的钱,也有可能吞掉你一定的钱,现在知道了它给你钱和星期几星期几有关,那么你会怎么办呢?
先不管那么多,作为一个程序猿直接开始搞程序啦!
假如我们知道周一到周日的利润是2,-5,5,-6,7,8,9,-5,-6,1,那么我们该从那一天买入呢?这就是我们要处理的问题?
先说下,假如不用二分法我们该怎么做。我们就可以采用比较暴力的手段,用双重for循环,依次判断以第一天,第二天,第三天....作为起点,先将第一天也就是2存储起来,作为最后赚的钱,然后依次加上后续天数的值,比如加上-5,先判断-5+2与2那个大,明显2大于-5,所以最后得到的值不可能是2+-5,但将下标和值暂存,继续加上第二个,2+-5+5,还是没有2大,加上第三个,还是没有2+(-5)+5+(-6),再加上第四个2+(-5)+5+(-6)+7此时比2大,可以将最终结果替换。
以上看代码:
int[] profit={2,-5,5,-6,7,8,9,-5,-6,1};
int price=profit[0];
int endindex,startindex=0;
for(int i=0;i<=10;i++)
{int temppric=0;
startindex=i;
for(int j=i+1;j<=10;j++)
{tempprice+=profit[j];
endindex=j;
if(price<tempprice)
{endindex=j;
price=tempprice;}
}
}
大概这样的思路就能得到最后的结果了。但是这个代码在处理大量数据的时候往往会力不从心,我们就可以这样打算,将中间一拆二半,分别调用dichoto(开始,中间),dichoto(中间,结尾)
然后开始到最后差不多这样方法进行处理,这样就可以在大量数据时提高效率了,废话不说,看代码
package xxxx;import java.sql.Struct;
public class Dichotomy {
public static void main(String[] args) {
int[]a={2,-5,5,-6,7,8,9,-5,-6,1};
FIarray s=dichoto(0, 9, a);
System.out.println(s.endindex);
System.out.println(s.startindex);
System.out.println(s.total);
}
static FIarray dichoto(int origin,int end,int[] xx)
{if(origin==end)
{FIarray re=new FIarray();
re.startindex=origin;
re.endindex=end;
re.total=xx[origin];
return re;}
FIarray re1=dichoto(origin, (end+origin)/2, xx);
FIarray re2=dichoto((end+origin)/2+1, end, xx);
int money=xx[origin],money2=xx[(end+origin)/2+1];
int finalmoney=0;
int startpoint=(end+origin)/2,endpoint=(end+origin)/2+1;
for (int i = (end+origin)/2; i >=origin ; i--) {
finalmoney+=xx[i];
if (money<finalmoney) {
money=finalmoney;
startpoint=i;
}
}
finalmoney=0;
for (int j = (end+origin)/2+1; j <=end; j++) {
finalmoney+=xx[j];
if (money2<finalmoney) {
money2=finalmoney;
endpoint=j;
}
}
FIarray re3=new FIarray();
re3.startindex=startpoint;
re3.endindex=endpoint;
re3.total=money+money2;
if(re3.total>=re1.total&&re3.total>=re2.total)
return re3;
else if(re2.total>=re1.total&&re2.total>=re3.total)
return re2;
else
return re1;
}
}
class FIarray {
int startindex;
int endindex;// TODO Auto-generated method stub
int total;
}