欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java/653. Two Sum IV - Input is a BST 两数之和 IV - 输入 BST

程序员文章站 2022-06-17 19:47:46
...

题目

Java/653. Two Sum IV - Input is a BST 两数之和 IV - 输入 BST


Java/653. Two Sum IV - Input is a BST 两数之和 IV - 输入 BST

 

 

代码部分一(592ms)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    List<Integer> list = new ArrayList<Integer>();
    public boolean findTarget(TreeNode root, int k) {
        if(root == null)
            return false;
        changeList(root,k);
        boolean res = false;
        int len = list.size();
        if(len < 2)
            return false;
        for(int i = 0 ; i < len ; i++){
            for(int j = 0 ; j < len ; j++){
                if(i != j){
                    int temp = list.get(i) + list.get(j);
                    if(temp == k){
                        res = true;
                        break;
                    }
                }
                
            }
        }
        return res;
    }
    public void changeList(TreeNode root, int k){
        if(root.left != null)
            changeList(root.left, k);
	list.add(root.val);
        if(root.right != null)
            changeList(root.right, k);
    }
}
  1. 若树为空,返回 false
  2. 调用changeList()将树的所有节点值按中序遍历(正序)存入 list 中
  3. 若 list 长度小于2,直接返回false
  4. 调用两个循环遍历所有情况,若找到则返回 true
  5. 否则直接返回 res(false)

 

代码部分二(一改进 33ms)

class Solution {
    List<Integer> list = new ArrayList<Integer>();
    public boolean findTarget(TreeNode root, int k) {
        if(root == null)
            return false;
        changeList(root);
        boolean res = false;
        int i = 0, j = list.size() - 1;
        while(i < j){
            if(list.get(i) + list.get(j) == k){
                return true;
            }else if(list.get(i) + list.get(j) < k){
                i++;
            }else{
                j--;
            }
        }
        return res;
    }
    public void changeList(TreeNode root){
        if(root.left != null)
            changeList(root.left);
        list.add(root.val);
        if(root.right != null)
            changeList(root.right);
    }
}
  1. 此版本为一的改进版
  2. 中序遍历树,按正序将节点值存入 list
  3. 在while()中 从 list 的首尾元素(Min、Max)向中间值靠拢,直到找到符合值或循环条件不成立时跳出
  4. 若两个取值小于 K ,说明值偏小,此时应该将左值向左移一位
  5. 若两个取值大于K,说明值偏大,此时将右值向右移一位
  6. 最后返回 res

 

代码部分三(22ms)

class Solution {
    public boolean findTarget(TreeNode root, int k) {
        Set<Integer> set = new HashSet<Integer>();
        // 该方法未使用BST的特性,单纯从二叉树角度出发!!!
        return find(root, k, set);
    }
    
    public boolean find(TreeNode root, int k, Set<Integer> set){
        if(null == root){
            return false;
        }
        if(set.contains(k - root.val)){
            return true;
        }
        set.add(root.val);
        return find(root.left, k, set) || find(root.right, k, set);
    }
}
  1. 创建 set ,用于存储节点
  2. 返回find()函数
  3. 当前节点为空,返回 false
  4. 若目标值与当前节点的差 存在于 set 中,说明有两个节点使条件成立
  5. 每遍历一个值,将其存入 set
  6. 若左或右子树中存在使条件的两个节点,返回在 true , 否则返回false

 

代码部分四(19ms)

class Solution {
	public boolean findTarget(TreeNode root, int k) {
		forTree(root,root,k);
		return hasFind;
    }
	
	boolean hasFind = false;
	
	public void forTree(TreeNode rootDate,TreeNode root,int k){
		if (null == root)
			return;
		int need = k - root.val;
		TreeNode find = findK(rootDate, need);
		if (find != null && find != root) {
			hasFind = true;
		}
		forTree(rootDate, root.left, k);
		forTree(rootDate, root.right, k);
	}
	
	public TreeNode findK(TreeNode root, int k) {
		if (null != root){
			if (root.val == k) {
				return root;
			} else if (root.val > k) {
				TreeNode find = findK(root.left, k);
				if (find != null)
					return find;
			} else {
				TreeNode find = findK(root.right, k);
				if (find != null)
					return find;
			}
		}
		return null;
	}
}
  1. 调用fortree()
  2. 若当前节点为空,则返回null
  3. 取得目标值和当前节点的差值 need
  4. 调用函数findK(),找到与need相等的节点,并返回该节点
  5. 若存在节点,将hasFind赋值 true
  6. 遍历左子树和右子树