Java/653. Two Sum IV - Input is a BST 两数之和 IV - 输入 BST
程序员文章站
2022-06-17 19:47:46
...
题目
代码部分一(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);
}
}
- 若树为空,返回 false
- 调用changeList()将树的所有节点值按中序遍历(正序)存入 list 中
- 若 list 长度小于2,直接返回false
- 调用两个循环遍历所有情况,若找到则返回 true
- 否则直接返回 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);
}
}
- 此版本为一的改进版
- 中序遍历树,按正序将节点值存入 list
- 在while()中 从 list 的首尾元素(Min、Max)向中间值靠拢,直到找到符合值或循环条件不成立时跳出
- 若两个取值小于 K ,说明值偏小,此时应该将左值向左移一位
- 若两个取值大于K,说明值偏大,此时将右值向右移一位
- 最后返回 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);
}
}
- 创建 set ,用于存储节点
- 返回find()函数
- 当前节点为空,返回 false
- 若目标值与当前节点的差 存在于 set 中,说明有两个节点使条件成立
- 每遍历一个值,将其存入 set
- 若左或右子树中存在使条件的两个节点,返回在 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;
}
}
- 调用fortree()
- 若当前节点为空,则返回null
- 取得目标值和当前节点的差值 need
- 调用函数findK(),找到与need相等的节点,并返回该节点
- 若存在节点,将hasFind赋值 true
- 遍历左子树和右子树
上一篇: 二叉树【汇总】