今天看到了一个比较有意思的算法题,其实更有意思的是其解法,让人顿时有一种耳目一新的感觉,爱不释手,拿来分享一下。
题目:假设生成26个非负随即数,要求其和是301,求程序生成此列数字
哈哈,元芳,你如何看?
解法一: 关于此种算法原理,我们可以假想是一根长301单位的绳子,然后随即在其上面截25个点,于是得到26根子绳,这26根子绳之和恰好就是绳子总长301。
于是,我们可以:
- 初始化27的数组
- 该数组0位和26位分别为0和301,其他位置填充0到301之间的随即数字
- 对数组排序
- 数组相邻数字相减,所得的26个差值即为所求数列。
public static void main(String[] args) {
int[] arryTemp = new int[27];
int[] arryRandom = new int[26];
// get random number,from 0 to 301
Random ran = new Random((int) Calendar.getInstance().getTimeInMillis());
arryTemp[0] = 0;
arryTemp[26] = 301;
for (int i = 1; i < 26; i++) {
arryTemp[i] = ran.nextInt(301);
}
// sort the arry
int temp;
for (int m = arryTemp.length - 1; m > 0; m--) {
for (int n = 0; n < m; n++) {
if (arryTemp[m] < arryTemp[n]) {
temp = arryTemp[n];
arryTemp[n] = arryTemp[m];
arryTemp[m] = temp;
}
}
}
// get the lastest random arry
for (int j = 0; j < arryRandom.length; j++) {
arryRandom[j] = arryTemp[j + 1] - arryTemp[j];
}
// check the arry
int sum = 0;
for (int k = 0; k < arryRandom.length; k++) {
sum = sum + arryRandom[k];
}
System.out.println(sum);
}
public static void main(String[] args) {
int[] arryRandom = new int[26];
Random ran = new Random();
// add 1 301times into the arry
for (int i = 0; i < 301; i++) {
arryRandom[ran.nextInt(26)]++;
}
// chenck the arry
int sum = 0;
for (int j = 0; j < arryRandom.length; j++) {
System.out.println(arryRandom[j]);
sum = sum + arryRandom[j];
}
System.out.println(sum);
}