Java工程师面试---面试算法题(一)
2017-11-02 17:37
477 查看
一、阶乘问题:
阶乘结果包含零的个数:首先想到零是怎么出现的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<n;i+=5){ k++; sum=k; } return sum; }
二、 求给定数组的总和:
使用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进余下的空间
(第二步
1041f
在数组相等长度的时候 忽略)
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<n && k<length;i++,k+=2){ m[k]=arr1[i]; m[k+1]=arr2[i]; } for(;i<arr1.length&& k<length;i++,k++){ m[k]=arr1[i]; } for(;i<arr2.length&& k<length;i++,k++){ m[k]=arr2[i]; } return m; }
四、斐波拉契数
编写一个计算前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
,f[n-1]) (n>2)
五、组建最大的数
编写一个能将给定非负整数列表中的数字排列成最大数字的函数。例如,给定[50,2,1,9],最大数字为95021。此处最大突破点就是比较两个数 顺序 导致结果变化,(前+后 ).compareTo(后+前)
public void co(String[] a){ String temp=""; //排序法:冒泡泡排序,从小到大 for(int i=0;i<a.length-1;i++){ for(int j=0;j<a.length-i-1;j++){ if(compare(a[j+1],a[j])>0){ temp=a[j+1]; a[j+1]=a[j]; a[j]=temp; } } } StringBuffer sb=new StringBuffer(); for(int i=0;i<a.length ;i++) sb.append(a[i]); System.err.println(sb.toString()); } //比较哪个数大 public int compare(String a1,String a2){ return (a1+a2).compareTo(a2+a1); }
六、算出指定的数
编写一个在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<String> list = new ArrayList<String>(); ArrayList<String> opeator = new ArrayList<String>(); 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 毫秒
相关文章推荐
- 【LeetCode-面试算法经典-Java实现】【023-Merge k Sorted Lists(合并k个排好的的单链表)】
- 资深算法工程师万宫玺:Java工程师转型AI的秘密法宝——深度学习框架Deeplearning4j | 分享总结
- 【LeetCode-面试算法经典-Java实现】【070-Set Matrix Zeroes(矩阵置零)】
- JVM知识点总览-高级Java工程师面试必备
- 【LeetCode-面试算法经典-Java实现】【026-Remove Duplicates from Sorted Array(删除排序数组中的重复元素)】
- 【LeetCode-面试算法经典-Java实现】【165-Compare Version Numbers(比较版本号)】
- 面试总结——Java高级工程师(三)
- java面试算法与设计(高级)
- 一些Java面试中经常出现的算法题
- 阿里面试Java开发工程师
- 【LeetCode-面试算法经典-Java实现】【074-Search a 2D Matrix(搜索二维矩阵)】
- 【LeetCode-面试算法经典-Java实现】【079-Word Search(单词搜索)】
- 【LeetCode-面试算法经典-Java实现】【035-Search Insert Position(搜索插入位置)】
- 面试的角度诠释 Java 工程师(一)(上)
- 面试10大算法汇总+常见题目解答(Java)
- Java工程师的一些面试总结(8)
- 面试总结 —— 高级JAVA工程师
- 【LeetCode-面试算法经典-Java实现】【015-3 Sum(三个数的和)】
- 最全常见算法工程师面试题目整理
- 【LeetCode-面试算法经典-Java实现】【073-Climbing Stairs(爬楼梯)】