1. 程式人生 > >兩數之和。給定一個二叉搜索樹和一個目標結果,如果 BST 中存在兩個元素且它們的和等於給定的目標結果,則返回 true

兩數之和。給定一個二叉搜索樹和一個目標結果,如果 BST 中存在兩個元素且它們的和等於給定的目標結果,則返回 true

pro 使用數組 log out clip pri 試用 false margin

題目來源:https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/

給定一個二叉搜索樹和一個目標結果,如果 BST 中存在兩個元素且它們的和等於給定的目標結果,則返回 true。

技術分享圖片

測試用例中的樹按層遍歷為[5,3,6,2,4,null,7]

測試用例表示為(包含多個測試用例):

[5,3,6,2,4,null,7]  9

[5,3,6,2,4,null,7]  28

[2,1,3]       4

[2,0,3,-4,1]    -1

二叉搜索樹的性質:

  • 可以是一顆空樹
  • 若存在左子樹,則左子樹所有節點的值都小於(是小於,不包括等於)根節點的值,若存在右子樹,則根節點的值大於右子樹所有節點的值

結合二叉搜索樹的性質,我們可以想到,二叉搜索樹的中序遍歷是一個遞增的有序數列

得出思路:

  1. 中序遍歷二叉搜索樹,得到一個數組,這裏用Vector存放樹節點值,因為不確定樹節點的個數,否則使用數組更方便,設為v。
  2. 從v值查找和數,若找到返回true,找不到返回false(為方便,下面將向量v用數組的形式進行表示)

從v的最後一個值開始v[j](j=n-1),比較v[j]和target/2的大小,

1)若v[j]<target/2直接返回false(因為v[j]是最大的值,若v[j]小於target/2,在v的其他值一定小於target/2,肯定是沒有兩個數的和等於target。)

2)若v[j]>target/2則對比v[j]+v[i](i=0),

2.1)若v[j]+v[i]=target,返回true;

2.2)若v[j]+v[i]<target,則i++;

2.3)若v[j]+v[i]>target,則j--

java實現:

    public boolean findTarget(TreeNode root, int k) {
        Vector v = new Vector();
        traverse1(root,k,v);
        return find(v,k);
    }
    
private void traverse(TreeNode root, int k, Vector v){ if(root == null) return; if(root.left != null){ traverse(root.left, k, v); } v.addElement(root.val); //System.out.print(root.val+"\t"); if(root.right != null){ traverse(root.right, k, v); } } private boolean find(Vector v, int k){ int n = v.size(); if(n > 0){ for(int j = n-1; j>0; j--){ if((int)v.get(j) > k/2){ // 2) for(int i=0; i<j; i++){ int add = (int)v.get(j) + (int)v.get(i); if(add == k){ return true; // 2.1) }else if(add > k){ break; //2.3) } } }else{ return false;// 1) } } } return false; }

該算法的執行時間效率很高,但消耗的內存多,因為使用了vector存放數據(註意要在LeetCode上要import vector)。

要想在IDE(eclipse)中調試,請參考博客《如何在IDE(eclipse)中debug LeetCode的樹算法》

為了得到而努力

2019-04-05

轉載請註明來處

兩數之和。給定一個二叉搜索樹和一個目標結果,如果 BST 中存在兩個元素且它們的和等於給定的目標結果,則返回 true