##一、阶乘问题:
阶乘结果 从个位到倒数 连续为零的个数:
首先想到零是怎么出现的10的倍数相乘即可,即 (5*2)*n n为任意的数。
1、2 只要是偶数 都包含2.而包括5的只存在位数为0或者5的数里面
2、所有2的个数 远远多于5的个数,故只要统计五的个数
3、每加一个五,数字就多一个5,减少乘法运算。
需要消耗o(1)的空间和o(n/5)的时间
public void countZero(int n){
int k=0,sum=0;
if(n<5)
retrurn 0;
for(int i=5;i
##二、 求给定数组的总和:
使用for循环、while循环和递归写出3个函数来计算给定数列的总和。
就是叠加数组:
public int sum(int[] k) {
int sum = 0;
for (int i = 0; i < k.length; i++)
sum += k[i];
return sum;
}
public int sum2(int[] k) {
int sum = 0, i = 0;
while (i < k.length)
sum += k[i++];
return sum;
}
public int sum3(int[] k, int m) {
if (k.length == m + 1) {
return k[m];
}
return k[m] + sum3(k, m + 1);
}
##三、交错合并数组
编写一个交错合并列表元素的函数。例如:给定的两个列表为[a,B,C]和[1,2,3],函数返回[a,1,B,2,C,3]。
有点类似于归并排序,合并两个数组。这里面使用交错排序。
第一步:按照最短的数 完成2*min(length)长度,
第二步:再将剩余的数copy进余下的空间
(第二步 在数组相等长度的时候 忽略)
public int[] merge(int[] arr1, int[] arr2) {
int length = arr1.length + arr2.length;
int n = arr1.length > arr2.length ? arr2.length : arr1.length;
int[] m = new int[length];
int i=0;
int k=0;
for(;i
##四、斐波拉契数
编写一个计算前100位斐波那契数的函数。根据定义,斐波那契序列的前两位数字是0和1,随后的每个数字是前两个数字的和。例如,前10位斐波那契数为:0,1,1,2,3,5,8,13,21,34。
首先想到暴力算法:反复计算之前的数值,然后计算出结果。
###4、1暴力算法
####4.2.1、前一百个拉斐波切数:
public Long[] f() {
Long[] arr = new Long[100];
int n = 0;
arr[n++] = 0L;
arr[n++] = 1L;
for (int i = n; i < 100; i++)
arr[i] = arr[i - 1] + arr[i-2];
return arr;
}
算到第94个的时候,数据越界了。没办法8个字节的long都不够用。该方法走不通。
第91个值是: 4660046610375530309
第92个值是: 7540113804746346429
第93个值是: -6246583658587674878
第94个值是: 1293530146158671551
####4.2.2、使用BigDecimal方法计算:
public String[] f() {
String[] arr = new String[100];
int n = 0;
arr[n++] = "0";
arr[n++] = "1";
for (int i = n; i < 100; i++)
arr[i] = add(arr[i - 1] , arr[i - 2]);
return arr;
}
public String add(String a, String b) {
BigDecimal d1 = new BigDecimal(a);
BigDecimal d2 = new BigDecimal(a);
return d1.add(d2).toString();
}
结果是:
花费时间 7ms
第90个值是: 618970019642690137449562112
第91个值是: 1237940039285380274899124224
第92个值是: 2475880078570760549798248448
第93个值是: 4951760157141521099596496896
第94个值是: 9903520314283042199192993792
第95个值是: 19807040628566084398385987584
第96个值是: 39614081257132168796771975168
第97个值是: 79228162514264337593543950336
第98个值是: 158456325028528675187087900672
第99个值是: 316912650057057350374175801344
####4.2.3使用BigInteger
public BigInteger[] f2() {
BigInteger[] arr = new BigInteger[100];
int n = 0;
arr[n++] = new BigInteger("0");
arr[n++] = new BigInteger("1");
for (int i = n; i < 100; i++)
arr[i] = arr[i - 1].add(arr[i - 2]);
return arr;
}
时间是3ms
###4.2 扩展–计算第几位的斐波拉契数
####1、暴力算法,使用上面的算法,打印第几次的结果
时间复杂度是 o(n),空间复杂度是o(1)
####2、 简化算法:
前几位斐波拉契数:0 1 1 2 3 5 8…
当n大于2的时候,第n位数等于第n-1位+第n-2位之和。
第一种思路:使用递归算法 计算出
时间复杂度是o(n),空间复杂度时o(2*n)
function a(n){
if(n<=0)
return;
if(n==1)
return 0;
else if(n==2)
return 1;
else
return a(n-1)+a(n-2);
}
####第二种算法:
(1 ,0) *()=(3,1)
(3 ,1) *()=(5, 3) (1 ,0) ()()=(5, 3)
…
以此类推,只要计算出()里面的数,就可以用公式一步计算出最终的结果。
很容易的使用行列式(不会的可以看看线性代数 )就计算出()={{1,1},{1,0}}
划分计算模块
n<3直接得出结果
n>2
1、行列式幂次方的计算方法
2、幂次方的结果乘以(1,0)即可得到(f[n],f[n-1]) (n>2)
##五、组建最大的数
编写一个能将给定非负整数列表中的数字排列成最大数字的函数。例如,给定[50,2,1,9],最大数字为95021。
此处最大突破点就是比较两个数 顺序 导致结果变化,(前+后 ).compareTo(后+前)
public void co(String[] a){
String temp="";
//排序法:冒泡泡排序,从小到大
for(int i=0;i0){
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
}
}
StringBuffer sb=new StringBuffer();
for(int i=0;i
##六、算出指定的数
编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100。
###1、暴力算法,穷举
/**
* 采取穷举的方法,测试是否符合条件
*/
@Test
public void aa() {
byte[] c = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
byte[] b = new byte[8];
String res = "";
for (int i = 0; i < 6561; i++) {
if ((res = getRes(b, c)) != null) {
System.err.println(res);
}
addBy3(b);
}
}
/**
*
* @param b
* 数字字符集
* @param c
* 数字之间的操作可能
* @return 等于100的操作的四则运算
*/
public String getRes(byte[] b, byte[] c) {
ArrayList list = new ArrayList();
ArrayList opeator = new ArrayList();
list.add(String.valueOf(c[0]));
// 合并无操作符的位置
for (int j = 0; j < b.length; j++) {
if (b[j] == 0) {
list.set(list.size() - 1,
list.get(list.size() - 1) + String.valueOf(c[j + 1]));
} else if (b[j] == 1) {
list.add(String.valueOf(c[j + 1]));
opeator.add("+");
} else if (b[j] == 2) {
list.add(String.valueOf(c[j + 1]));
opeator.add("-");
}
}
// 记录本次操作的情况
StringBuilder sb = new StringBuilder();
// 因为最大结果是9位数 超出int
BigInteger sum = new BigInteger(list.get(0));
sb.append(list.get(0));
// 计算
for (int j = 0; j < opeator.size(); j++) {
sb.append(opeator.get(j) + list.get(j + 1));
if (opeator.get(j).equals("+")) {
sum = sum.add(new BigInteger(list.get(j + 1)));
} else if (opeator.get(j).equals("-")) {
sum = sum.subtract(new BigInteger(list.get(j + 1)));
} else {
}
}
String s = sum.toString();
if ("100".equals(s))
return sb.toString();
else
return null;
}
/**
* 三进制加法,满2 清零 进一;最长为8位数
*
* @param c
*/
public void addBy3(byte[] c) {
for (int i = c.length - 1; i >= 0; i--) {
if (c[i] == 2) {
c[i] = 0;
continue;
} else {
c[i] += (byte) 1;
break;
}
}
}
123+45-67+8-9
123+4-5+67-89
123-45-67+89
123-4-5-6-7+8-9
12+3+4+5-6-7+89
12+3-4+5+67+8+9
12-3-4+5-6+7+89
1+23-4+56+7+8+9
1+23-4+5+6+78-9
1+2+34-5+67-8+9
1+2+3-4+5+6+78+9
运算时间43 毫秒