面試題4-演算法
本文是為了總結面試的時候經常會遇到的演算法面試題,面試之前回顧一下這些演算法題有助於調高成功率。所有演算法的實現都是基於Java,希望對各位讀者有幫助!!!
1.最長公共子串
public int LCS (String str1, String str2) { int length = str1.length(); int high = str2.length(); int result = 0; int[][] arr = new int[length+1][high+1]; for (int i = 1; i < arr.length; i++) { for (int j = 1; j < arr[i].length; j++) { if (str1.charAt(i-1)==str2.charAt(j-1)) { if (arr[i-1][j-1] == 0) { arr[i][j] = 1; } else { arr[i][j] = arr[i-1][j-1] + 1; } } if (arr[i][j] > result) { result = arr[i][j]; } } } return result; }
2.二叉樹中兩個節點的最近的公共父節點
這個問題分為幾種情況:
1)如果遍歷節點的左右子樹分別存在找查詢的兩個節點,那麼遍歷的節點就是最近的公共父節點;
2)如果遍歷節點的左子樹或者右子樹存在目標節點,返回存在的節點;
3)如果要遍歷的節點的左子樹和右子樹都查不到目標節點,返回null;
public Integer findAncestor(TreeNode root, int child1, int child2) { if (root == null) { return null; } if (root.value == child1 || root.value == child2) { return root.value; } Integer left = getParent(root.leftNode, child1, child2); Integer right = getParent(root.rightNode, child1, child2); if (left != null && right != null) { return root.value; } if (left == null && right == null) { return null; } return left==null?right:left; }
3.根節點到某個節點的路徑
public String getPath(TreeNode root, int target, String path) { if (root== null) { return path; } path+=root.value; if (root.value == target) { return path; } path = getPath(root.leftNode, target, path); path = getPath(root.rightNode, target, path); if (!path.equals("") && !path.endsWith(target+"")) { //刪除的是否一定要加入判斷,否則只會輸出一個元素 path = path.substring(0, path.length()-1); } return path; }
4.全排列(有重複元素、沒有重複元素)
注意:下面只列出了沒有重複元素的程式碼,有重複元素的話,加入判斷
private void allPermutation(char[] c, LinkedList<String> listStr, int start){ if(start == c.length-1) listStr.add(String.valueOf(c)); else{ for(int i = start; i <= c.length-1; i++) { swap(c, i, start);//相當於: 固定第 i 個字元 allPermutation(c, listStr, start+1);//求出這種情形下的所有排列 swap(c, start, i);//復位,一定要復位,如果不復位下次迴圈的交換會亂套 } } } private void swap(char[] c, int i, int j){ //交換元素 char tmp = c[i]; c[i] = c[j]; c[j] = tmp; }
5.堆排序
注意:要注意堆的構建,大(小)堆的構建和替換元素之後的重新調整都要會,查詢前K個最大的元素,用小頂堆實現的。
public static void heapSort(int[] array) { if (array == null || array.length == 1) { return; } int j = 0; for (int i = array.length-1; i >= 0; i--) { maxHeapify(array, array.length-j); swap(array, 0, array.length-1-j); j++; } }
public static void maxHeapify(int[] arrays, int size) { // 從陣列的尾部開始,直到第一個元素(角標為0) for (int i = size - 1; i >= 0; i--) { buildMaxHeap(arrays, size, i); } }
private static void swap(int[] array, int i, int j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; }
private static void buildMaxHeap(int[] array, int heapSize, int index) { int left = 2*index+1; int right = 2*index+2; int max = index; if (left < heapSize && array[left] > array[max]) { max = left; } if (right < heapSize && array[right] > array[max]) { max = right; } if (max != index) { swap(array, index, max); buildMaxHeap(array, heapSize, max); } }