1. 程式人生 > >日常演算法題(三)

日常演算法題(三)

1.對稱二叉樹

給定一個二叉樹,檢查它是否是映象對稱的。

例如,二叉樹 [1,2,2,3,4,4,3] 是對稱的。 但是下面這個 [1,2,2,null,3,null,3] 則不是映象對稱的:

想法:直接遞迴遍歷判斷是否相等即可

程式碼:

	public boolean isSymmetric(TreeNode root) {
	    return isMirror(root, root);
	}

	public boolean isMirror(TreeNode t1, TreeNode t2) {
	    if (t1 == null && t2 == null) return true;
	    if (t1 == null || t2 == null) return false;
	    return (t1.val == t2.val)
	        && isMirror(t1.right, t2.left)
	        && isMirror(t1.left, t2.right);
	}

2.二叉樹的深層遍歷

給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問所有節點)。

例如: 給定二叉樹: [3,9,20,null,null,15,7], 返回其層次遍歷結果: [ [3], [9,20], [15,7] ]

想法:用DFS遍歷即可

程式碼:

public void levelHelper(List<List<Integer>> res, TreeNode root, int height) {
        if (root == null) return;
        if (height >= res.size()) {
            res.add(new LinkedList<Integer>());
        }
        res.get(height).add(root.val);
        levelHelper(res, root.left, height+1);
        levelHelper(res, root.right, height+1);
    }

3.求根到葉子節點子數之和

給定一個二叉樹,它的每個結點都存放一個 0-9 的數字,每條從根到葉子節點的路徑都代表一個數字。 例如,從根到葉子節點路徑 1->2->3 代表數字 123。

計算從根到葉子節點生成的所有數字之和。

說明: 葉子節點是指沒有子節點的節點。

示例 1:

輸入: [1,2,3] 1 / \ 2 3 輸出: 25 解釋: 從根到葉子節點路徑 1->2 代表數字 12. 從根到葉子節點路徑 1->3 代表數字 13. 因此,數字總和 = 12 + 13 = 25. 示例 2:

輸入: [4,9,0,5,1] 4 / \ 9 0 / \ 5 1 輸出: 1026 解釋: 從根到葉子節點路徑 4->9->5 代表數字 495. 從根到葉子節點路徑 4->9->1 代表數字 491. 從根到葉子節點路徑 4->0 代表數字 40. 因此,數字總和 = 495 + 491 + 40 = 1026.

想法:依舊是先根據題意依次遍歷並設定返回路徑的演算法

程式碼:

public int sumNumbers(TreeNode root) {
	return sum(root, 0);
}

public int sum(TreeNode n, int s){
	if (n == null) return 0;
	if (n.right == null && n.left == null) return s*10 + n.val;
	return sum(n.left, s*10 + n.val) + sum(n.right, s*10 + n.val);
}

4.刪除連結串列中的節點

請編寫一個函式,使其可以刪除某個連結串列中給定的(非末尾)節點,你將只被給定要求被刪除的節點。

現有一個連結串列 – head = [4,5,1,9],它可以表示為:

4 -> 5 -> 1 -> 9

示例 1:

輸入: head = [4,5,1,9], node = 5 輸出: [4,1,9] 解釋: 給定你連結串列中值為 5 的第二個節點,那麼在呼叫了你的函式之後,該連結串列應變為 4 -> 1 -> 9. 示例 2:

輸入: head = [4,5,1,9], node = 1 輸出: [4,5,9] 解釋: 給定你連結串列中值為 1 的第三個節點,那麼在呼叫了你的函式之後,該連結串列應變為 4 -> 5 -> 9. 說明:

連結串列至少包含兩個節點。 連結串列中所有節點的值都是唯一的。 給定的節點為非末尾節點並且一定是連結串列中的一個有效節點。 不要從你的函式中返回任何結果。

想法:依舊是用連結串列刪除方法,不過只是要求多了些而已

程式碼:

public class Solution {
    public void deleteNode(ListNode node) {
        if(node != null && node.next != null) {
            node.val = node.next.val;
            node.next = node.next.next;
        }
    }
}

5.區域檢索-陣列不可變

給定一個整數陣列 nums,求出陣列從索引 i 到 j (i ≤ j) 範圍內元素的總和,包含 i, j 兩點。

示例:

給定 nums = [-2, 0, 3, -5, 2, -1],求和函式為 sumRange()

sumRange(0, 2) -> 1 sumRange(2, 5) -> -1 sumRange(0, 5) -> -3 說明:

你可以假設陣列不可變。 會多次呼叫 sumRange 方法。

想法:簡單題,從i到j索引並返回總和值即可

程式碼:

 public class NumArray {
    
   int[] nums;

public NumArray(int[] nums) {
    for(int i = 1; i < nums.length; i++)
        nums[i] += nums[i - 1];
    
    this.nums = nums;
}

public int sumRange(int i, int j) {
    if(i == 0)
        return nums[j];
    
    return nums[j] - nums[i - 1];
    }