二分法,二分法,简单来说就是将一个问题拆成二半,分成几个比较小的问题,在数据量以及计算次数比较多时候就能极大限度减少时间复杂度。
现在我们要处理一个这样的问题,比如我们算出某种数据的规律,要将一堆数据的走势算出来,为了不是很枯燥,咱就弄个好玩的例子吧,
例如你获得了个神器的瓶子,你可以每天向它要钱,它可能给你一定数量的钱,也有可能吞掉你一定的钱,现在知道了它给你钱和星期几星期几有关,那么你会怎么办呢?
话
额,没那么多钱还。。。先不管那么多,作为一个程序猿直接开始搞程序啦!
假如我们知道周一到周日的利润是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; }