LintCode/LeetCode訓練題目&答案詳解—基礎篇

weixin_34008784發表於2017-07-06

一、在二叉樹中尋找值最大的節點並返回:
給出如下一棵二叉樹:

     1
   /   \
 -5     2
 / \   /  \
0   3 -4  -5 

返回值為 3 的節點。

public class Solution {
    /**
 * @param root the root of binary tree
 * @return the max node
 */
public TreeNode maxNode(TreeNode root) {
    if (root == null) {
        return null;
    }
    return getMaxTreeNode(root);
}

private TreeNode getMaxTreeNode(TreeNode root) {
    if (root == null) {
        return new TreeNode(Integer.MIN_VALUE);
    }
    TreeNode left = getMaxTreeNode(root.left);
    TreeNode right = getMaxTreeNode(root.right);
    if (root.val > left.val && root.val > right.val) {
        return root;
    } else if (right.val > left.val && right.val > root.val) {
        return right;
    }
    return left;
}
 }

簡析:使用了遞迴的思想;注意為空的判斷;

二、單例

單例 是最為最常見的設計模式之一。對於任何時刻,如果某個類只存在且最多存在一個具體的例項,那麼我們稱這種設計模式為單例。例如,對於 class Mouse (不是動物的mouse哦),我們應將其設計為 singleton 模式。

你的任務是設計一個 getInstance 方法,對於給定的類,每次呼叫 getInstance 時,都可得到同一個例項。

樣例:
在 Java 中:

A a = A.getInstance();
A b = A.getInstance();
a 應等於 b.

挑戰:
如果併發的呼叫 getInstance,你的程式也可以正確的執行麼?

class Solution {
private volatile static  Solution mInstance = null;
/**
* @return: The same instance of this class every time
*/
public static Solution getInstance() {
    if (mInstance == null) {
        synchronized(Solution.class) {
            if (mInstance == null) {
                mInstance = new Solution();    
            }
        }
    }
    return mInstance;
}

private Solution() {}

}

注意:實現一個單例有兩點注意事項,①將構造器私有,不允許外界通過構造器建立物件;②通過公開的靜態方法向外界返回類的唯一例項

參考:單例模式的幾種寫法對比:
http://wuchong.me/blog/2014/08/28/how-to-correctly-write-singleton-pattern/

三、整數排序

給一組整數,按照升序排序,使用選擇排序,氣泡排序,插入排序或者任何 O(n2) 的排序演算法。

樣例:
對於陣列 [3, 2, 1, 4, 5], 排序後為:[1, 2, 3, 4, 5]。

答案(java版本):

選擇排序:

public void sortIntegers(int[] A) {
    int i, j, min, temp, len = A.length;
    for (i = 0; i < len -1; i++) {
        min = i; //未排序序列中最小資料陣列下標
        for (j = i + 1; j < len; j++) { //在未排序元素中繼續尋找最小元素,並儲存其下標
            if (A[min] > A[j]) {
                min = j;
            }
        }
        if (i != min) { //將最小元素放到已排序序列的末尾
            temp = A[min];
            A[min] = A[i];
            A[i] = temp;
        }
    }    
}

氣泡排序:

public void sortIntegers(int[] A) {
    int i, j, temp, len = A.length;
    for (i = 0; i < len - 1; i++) {
        for (j = 0; j < len - i - 1; j ++)
        if (A[j] > A[j+1]) {
            temp = A[j+1];
            A[j+1] = A[j];
            A[j] = temp;
        }
    }
    
}

答案解析:
各個語言的實現請參考維基百科:https://zh.wikipedia.org/wiki/%E9%80%89%E6%8B%A9%E6%8E%92%E5%BA%8F

** 四、斐波那契數列**

查詢斐波納契數列中第 N 個數。所謂的斐波納契數列是指:
前2個數是 0 和 1 。
第 i 個數是第 i-1 個數和第i-2 個數的和。
斐波納契數列的前10個數字是:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ...

答案:

public int fibonacci(int n) {
    // write your code here
    int a1 = 0;
    int a2 = 1;
    int result = 0;
    if (n == 1) {
        return a1;
    }
    if (n == 2) {
        return a2;
    }
    for (int i = 3; i <= n; i++) {
        result = a1 + a2;
        a1 = a2; 
        a2 = result;
    }
    return result;
}

注意事項:
1、n是從1開始的,而不是0
2、一般我們都會想到用遞迴的方式實現,但是這個時間開銷很大:

int fibonacci(int n) { 
  if (n == 1)
      return 0;
  else if (n == 2)
      return 1;
  return fib(n-1) + fib(n-2);
}

3、題目的引申: 青蛙跳階梯,鋪方磚
參考:http://www.bubuko.com/infodetail-1099705.html

相關文章