求一个数组中从L-R的和
给定一个无序数组array,需要大量从数组求从L-R的和时,设计一个数据结构,使这一过程高效。
思路:做一个辅助数组,记录从 0-i 的和,之后每次求L-R和时,只需获取 preSum[R]-preSum[L-1] 的值即可,注意当L=0时,直接获取preSum[R]即可。
static int[] preSum;
public static void rangeSum2(int[] array){
int N = array.length;
preSum = new int[N];
preSum[0] = array[0];
for(int i=1;i<N;i++){
preSum[i] = preSum[i-1] + array[i];
}
}
public static int rangeSum(int L,int R){
return L == 0 ? preSum[R] : preSum[R] - preSum[L - 1];
}
Math.random()方法返回的概率是原来的平方
Math.random()方法返回值的概率是等概率的,请写一个方法,使调用方法后,返回值的概率是值的平方。
public static double xToXPower2(int L,int R){
return Math.max(Math.random(),Math.random());
}
原理:Math.random()方法返回的是[0-1)的等概率的任意值,Math.max()会返回两次random中更大的一次,只有当两次random一样范围时才会返回本次random的数,所以其概率就变为了原来的平方。
从1-5随机到1-7随机
设有一个封装函数f(),f可以返回1-5的等概率随机数,请再设计一个函数g,使得可以返回1-7的随机数,不可使用其他随机函数。
思路:
1.将f函数的1-5随机回归到0-1随机,即返回值为1,2时定义为0,返回值为4,5时定义为1,返回值为3时再执行一遍f直到不为3时。
2.然后用二进制思路来解,一位二进制是0-1,二位二进制是0-3,三位二进制是0-7,只需随机三次,第一次的结果左移2位,第二次的结果左移1位,第三次不移位,然后相加就是0-7的等概率随机。
3.当结果等于7时,再执行一次,将0-7等概率转换为0-6等概率,最后结果+1即为1-7等概率。
public static int f1(){//1-5等概率
return (int)(Math.random() * 5)+1;
}
public static int f2(){//0-1等概率
int ans = 0;
do{
ans = f1();
}while(ans == 3);
return ans < 3 ? 0 : 1;
}
public static int f3(){//0-7等概率
int ans = (f2() << 2) + (f2() << 1) + (f2() << 0);
return ans;
}
public static int f4(){//0-6等概率
int ans = 0;
do{
ans = f3();
}while(ans == 7);
return ans;
}
public static int g(){//1-7等概率
return f4()+1;
}
扩展:a-b等概率到c-d等概率,都是将a-b先转化为0-1,c-d转化为0- (d-c),然后通过二进制思路,通过左移相加求解,最后结果+1即可。