在面試過程中,經常會碰到一些算法相關的編程題,對於初學者來說着實頭痛,下面就為大家梳理一下Java面試中一些比較常見的算法編程題;
如需轉載,請注明出處,謝謝!(文章將會持續更新)
代碼如下:
package com.tobiasy.toolkit.algorithm; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; /** * java中一些經典的算法(Algorithm) * * @author tobiasy */ public class ClassicJavaAlgorithm { /** * 問法一、斐波那契數或者費氏數列(Fibonacci數列) * 問法二、有一對兔子,從出生后第3個月起每個月都生一對兔子, * 小兔子長到第三個月后每個月又生一對兔子,假如兔子都不死, * 問每個月的兔子總數為多少? * 1 1 2 3 5 8 13 ... * <p> * 遞歸算法 * * @param n * @return */ public static Long getNumber(int n) { if (n < 0) { return -1L; } else if (n == 0) { return 0L; } else if (n == 1 || n == 2) { return 1L; } else { return getNumber(n - 1) + getNumber(n - 2); } } public static Long getFib(int n) { return n <= 0 ? -1L : n == 1 || n == 2 ? 1L : getFib(n - 1) + getFib(n - 2); } /** * 測試遞歸算法與傳統循環效率相比 */ public static final int MONTH = 40; public static void fib_test() { Long start = System.currentTimeMillis(); System.out.println(getFib(MONTH)); System.out.println("遞歸耗時:" + (System.currentTimeMillis() - start)); Long start1 = System.currentTimeMillis(); long f1 = 1L, f2 = 1L; long f; for (int i = 3; i <= MONTH; i++) { f = f2; f2 = f1 + f2; f1 = f; //System.out.print("第" + i +"個月的兔子對數: "); //System.out.println(" " + f2); } System.out.println(f2); System.out.println("非遞歸耗時:" + (System.currentTimeMillis() - start1)); } /** * 輸出結果: * 102334155 * 遞歸:1104 * 102334155 * 非遞歸:0 * 綜上,遞歸算法雖然代碼簡單,但在效率上面遠遠低於普通循環算法 */ /** * 計算100-999的水仙花數字 * 打印出所有的"水仙花數(narcissus number)",所謂"水仙花數"是指一個三位數, * 其各位數字立方和等於該數本身。 * 例如:153是一個"水仙花數",因為153=1的三次方+5的三次方+3的三次方。 * result 153 370 371 407 */ public static void narcissus() { for (int i = 100; i < 1000; i++) { int one = i / 100; int two = i / 10 % 10; int thr = i - i / 10 * 10; int res = one * one * one + two * two * two + thr * thr * thr; if (res == i) { System.out.println(i); } } } /** * 題目:獲取一個數以內的所有質數(素數) * * @param size */ public static List<Integer> getPrime(int size) { List<Integer> integers = new ArrayList<>(); for (int i = 2; i < size; i++) { boolean f = true; for (int j = 2; j < i; j++) { if (i % j == 0) { f = false; } } if (f) { integers.add(i); } } return integers; } /** * 題目:將一個正整數分解質因數。例如:輸入90,打印出90=2*3*3*5。 * 因式分解(factorization) * * @param num */ public static void factorization(int num) { int orinNum = num; List<Integer> is = getPrime(num + 1); List<Integer> res = new ArrayList<>(); for (int i = 0; i < is.size(); i++) { Integer integer = is.get(i); if (num % integer == 0) { res.add(integer); num = num / integer; i = 0; } } StringBuffer sf = new StringBuffer(); sf.append(orinNum + "="); for (int i = 0; i < res.size(); i++) { if (i < res.size() - 1) { sf.append(res.get(i) + "*"); } else { sf.append(res.get(i) + ""); } } System.out.println(sf.toString()); } /** * 題目:輸入兩個正整數,求其最小公倍數。 * * @param one * @param two * @return */ public static int leastCommonMultiple(int one, int two) { int max = one > two ? one : two; List<Integer> is = getPrime(max); for (Integer integer : is) { if (one % integer == 0 && two % integer == 0) { return integer; } } return -1; } /** * 題目:輸入兩個正整數,求其最小公倍數。 * * @param one * @param two * @return */ public static int leastCommonMultiple2(int one, int two) { int max = one > two ? one : two; List<Integer> is = getPrime(max); for (Integer integer : is) { if (one % integer == 0 && two % integer == 0) { return integer; } } return -1; } /** * 題目:輸入兩個正整數,求其最大公約數。 * * @param one * @param two */ public static int maxCommonDivisor(int one, int two) { int max = one * two; int min = one > two ? one : two; for (int i = min; i < max; i++) { if (i % one == 0 && i % two == 0) { return i; } } return max; } /** * 題目:使用System.currentTimeMillis()函數取得一個隨機的大寫字母(不能使用隨機函數) * 分析:這個題目的關鍵就是如何產生一個范圍在[65,90]的隨機數。 * 我們知道System.currentTimeMillis()返回系統距離1970-1-1 00:00:00分的毫秒數。 * 把它對26取余數就可以得到一個0~25的隨機數,這樣就產生了一個字母的相對索引。 * 這個隨機數再加上65就可以得到一個[65,90]的隨機數了 */ public static void getMaxChar() { Long curr = System.currentTimeMillis(); Long re = curr % 26; char c = (char) (re + 65); System.out.println(c); } /** * 題目:猴子吃桃問題 * 猴子第一天摘下若干個桃子,當即吃了一半,還不癮, * 又多吃了一個 第二天早上又將剩下的桃子吃掉一半,又多吃了一個。 * 以后每天早上都吃了前一天剩下 的一半零一個。到第10天早上想再吃時,見只剩下一個桃子了。 * 求第一天共摘了多少。 * result 1534 */ public static void monkeyEatPeach() { int sum = 1; for (int i = 1; i < 10; i++) { sum = (sum + 1) * 2; } System.out.println(sum); } /*** * 有一分數(Fraction)序列(sequence of number):2/1,3/2,5/3,8/5,13/8,21/13... * 求出這個數列的前20項之和 */ private static void sequenceOfNumFraction1(int size) { double no1 = 1, no2 = 2, res = no2 / no1; for (int i = 0; i < size - 1; i++) { double temp = no1; no1 = no2; no2 = no1 + temp; res += no2 / no1; } System.out.println(res); } private static void sequenceOfNumFraction2(int size) { int x = 2, y = 1, t; double sum = 0; DecimalFormat df = new DecimalFormat("#0.00000000000000"); for (int i = 1; i <= size; i++) { sum += (double) x / y; t = y; y = x; x = y + t; } System.out.println(df.format(sum)); } /** * 題目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一個數字。例如2+22+222+2222+22222(此時共有5個數相加),幾個數相加有鍵盤控制。 * 關鍵是計算出每一項的值 * 1、獲取n個2 * 2、累加 */ public static void calculate2Addition(int size) { int num = 2; Long sum = 2L; for (int i = 2; i <= size; i++) { sum = sum + sameNum(num, i); } System.out.println(sum); } /** * 獲取n個2 * * @param num * @param sum * @return */ private static Long sameNum(int num, int sum) { Long res = 0L; for (int i = 0; i < sum; i++) { if (i < sum - 1) { res = (res + num) * 10; } else { res = (res + num); } } return res; } /** * 將數值的人民幣轉化為大寫 * 例如:123456789 轉化為大寫后變成:壹億貳仟叄佰肆拾伍萬陸仟柒佰捌拾玖元 */ private static final char[] data = new char[]{'零','壹','貳','叄','肆','伍','陸','柒','捌','玖'}; private static final char[] units = new char[]{'元','拾','佰','仟','萬','拾','佰','仟','億'}; public static String convert(int money) { StringBuffer sb = new StringBuffer(); int unit = 0; while (money != 0){ sb.insert(0, units[unit++]); int number = money % 10; sb.insert(0, data[number]); money /= 10; } return sb.toString(); } }
其他算法編程推薦
1、編程算法經典案例
2、數組算法經典實例
其他文章推薦
Java自學教程推薦
1、Java自學教程(java,python,大數據,前端,計算機書籍)