1.给出一个数组,要求在O(n)的时间内找到三个点,由这三个点确定的四段数组里的元素和相等,也就是找四等分点。
当我们想要找一个二等分点的时候只需要用一个模拟指针依次指向每一个元素,直到元素前后的和相等。这里找四等分点的原理相等,用三个模拟指针指向三个位置,通过比较和调整这三个指针的位置找到合适的划分。具体代码:
public int[] four(int[] a){
int length=a.length-1;
int firstPosition=1;
int secondPosition=3;
int thirdPosition=5;
int sum1,sum2,sum3,sum4;
do{
sum1=sum2=sum3=sum4=0;//计算四段的值
for(int i=0;i<firstPosition;i++){
sum1+=a[i];
}
for(int i=firstPosition+1;i<secondPosition;i++){
sum2+=a[i];
}
for(int i=secondPosition+1;i<thirdPosition;i++){
sum3+=a[i];
}
for(int i=thirdPosition+1;i<=length;i++){
sum4+=a[i];
}
if (sum1<sum2) {
sum1+=a[firstPosition];
sum2-=a[firstPosition+1];
firstPosition++;
} else if(sum1>sum2){
if(secondPosition<length){
sum2+=a[secondPosition];
sum3-=a[secondPosition+1];
secondPosition++;
}
}
if (sum2<sum3) {
if(secondPosition<length){
sum2+=a[secondPosition];
sum3-=a[secondPosition+1];
secondPosition++;
}
} else if(sum2>sum3){
if(thirdPosition<length){
sum3+=a[thirdPosition];
sum4-=a[thirdPosition+1];
thirdPosition++;
}
}
if (sum3<sum4) {
if(thirdPosition<length){
sum3+=a[thirdPosition];
sum4-=a[thirdPosition+1];
thirdPosition++;
}
} else if(sum3>sum4){
thirdPosition=length;
}
}while(!(sum1==sum2&&sum2==sum3&&sum3==sum4)&&secondPosition!=length&&thirdPosition!=length);
int[] result=new int[3];
if (secondPosition==length||thirdPosition==length) {
result=null;
} else {
result[0]=firstPosition+1;
result[1]=secondPosition+1;
result[2]=thirdPosition+1;
}
return result;
}
这里我用了四个Int来表示模拟指针指向的位置,四个Int表示四段的和。主体是一个do while循环,跳出条件是四段和相同或者二号三号指针指向末尾(可以代入数据进行测试,无法找到等分点的时候二号或者三号指针是指向末尾的)。
循环体里是几组判断,比如第一段和第二段的比较,第一段小的话就让一号指针后移,第一段增加,第二段减少。后面的比较和处理同理。
返回值是储存了三个位置的数组,没找到的话返回null
2.指数快速幂:
计算一个double的int次幂。这个指数int非常大,不能直接计算。
思路是这样的,如果要计算0.7的9次幂,可以看做(0.7)^2^2^2 *0.7,这样只进行了4次乘法。也就是说,Int型的指数可以看成二进制数,比如9是1001,=8+1,只需要算八次方和一次方即可。代码:
public double multify(double n,int k){//指数快速幂
double result=1.0d;
double temp=n;
while(k>0){
if (k%2==1){//奇数,最后一位是1,进行计算
result=result*temp;
}
temp=temp*temp;
k=k>>1;
}
return result;
}
每次判断k的最低位是否是1,如果是就进行计算,每次k右移一位,中间变量temp平方。