一、二叉搜索树的应用
1. 700【二叉搜索树中的搜索】
题目: 给定二叉搜索树(BST)的根节点 root 和一个整数值 val。你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。代码:
class Solution { public TreeNode searchBST ( TreeNode root, int val) { if ( root== null ) return null ; if ( root. val== val) return root; if ( root. val > val) { root = searchBST ( root. left, val) ; } else { root = searchBST ( root. right, val) ; } return root; }
}
2. 98【验证二叉搜索树】
题目: 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。有效二叉搜索树定义如下: 节点的左子树只包含 小于 当前节点的数。 节点的右子树只包含 大于 当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树。 代码:
class Solution { public boolean isValidBST ( TreeNode root) { List < Integer > inorder = new LinkedList < > ( ) ; traversal ( root, inorder) ; for ( int i = 1 ; i < inorder. size ( ) ; i++ ) { if ( inorder. get ( i- 1 ) >= inorder. get ( i) ) { return false ; } } return true ; } public void traversal ( TreeNode root, List < Integer > inorder) { if ( root == null ) return ; traversal ( root. left, inorder) ; inorder. add ( root. val) ; traversal ( root. right, inorder) ; }
}
3. 530【二叉搜索树的最小绝对差】
题目: 给你一个二叉搜索树的根节点 root ,返回树中任意两不同节点值之间的最小差值 。差值是一个正数,其数值等于两值之差的绝对值。代码:
class Solution { public int min = Integer . MAX_VALUE ; public TreeNode pre; public int getMinimumDifference ( TreeNode root) { traversal ( root) ; return min; } public void traversal ( TreeNode root) { if ( root == null ) return ; traversal ( root. left) ; if ( pre != null ) { int sub = Math . abs ( pre. val- root. val) ; min = sub> min ? min: sub; } pre = root; traversal ( root. right) ; }
}
4. 501【二叉搜索树中的众数】
题目: 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。代码:
class Solution { public TreeNode pre = null ; public int count = 0 ; public int max = 0 ; public int [ ] findMode ( TreeNode root) { ArrayList < Integer > list = new ArrayList < > ( ) ; traversal ( root, list) ; int [ ] ansList = new int [ list. size ( ) ] ; for ( int i = 0 ; i < list. size ( ) ; i++ ) { ansList[ i] = list. get ( i) ; } return ansList; } public void traversal ( TreeNode root, ArrayList < Integer > list) { if ( root == null ) return ; traversal ( root. left, list) ; if ( pre== null || pre. val!= root. val) { count = 1 ; } else { count++ ; } if ( count > max) { max = count; list. clear ( ) ; list. add ( root. val) ; } else if ( count == max) { list. add ( root. val) ; } pre = root; traversal ( root. right, list) ; }
}
5. 701【二叉搜索树中的插入操作】
题目: 给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。 注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。代码:
class Solution { public TreeNode insertIntoBST ( TreeNode root, int val) { if ( root == null ) { return new TreeNode ( val) ; } if ( root. val> val) { root. left = insertIntoBST ( root. left, val) ; } if ( root. val< val) { root. right = insertIntoBST ( root. right, val) ; } return root; }
}
6. 450【删除二叉搜索树中的节点】
题目: 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。 一般来说,删除节点可分为两个步骤: 代码:
class Solution { public TreeNode deleteNode ( TreeNode root, int key) { if ( root == null ) return root; if ( root. val == key) { if ( root. left== null && root. right!= null ) { return root. right; } else if ( root. left!= null && root. right== null ) { return root. left; } else if ( root. left== null && root. right== null ) { return null ; } else { TreeNode node = root. right; while ( node. left!= null ) { node = node. left; } node. left = root. left; return root. right; } } if ( root. left!= null ) root. left = deleteNode ( root. left, key) ; if ( root. right!= null ) root. right = deleteNode ( root. right, key) ; return root; }
}
7. 669【修剪二叉搜索树】
题目: 给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。 所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。代码:
class Solution { public TreeNode trimBST ( TreeNode root, int low, int high) { if ( root == null ) return root; if ( root. val< low) { return trimBST ( root. right, low, high) ; } else if ( root. val> high) { return trimBST ( root. left, low, high) ; } root. left = trimBST ( root. left, low, high) ; root. right = trimBST ( root. right, low, high) ; return root; }
}
8. 108【将有序数组转换为二叉搜索树】
题目: 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡二叉搜索树。 高度平衡二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。代码:
class Solution { public TreeNode sortedArrayToBST ( int [ ] nums) { return traversal ( nums, 0 , nums. length) ; } public TreeNode traversal ( int [ ] nums, int left, int right) { if ( left>= right) { return null ; } int mid = left+ ( right- left) / 2 ; TreeNode node = new TreeNode ( nums[ mid] ) ; node. left = traversal ( nums, left, mid) ; node. right = traversal ( nums, mid+ 1 , right) ; return node; }
}
9. 538【把二叉搜索树转换为累加树】
题目: 给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。代码:
class Solution { int sum = 0 ; public TreeNode convertBST ( TreeNode root) { traversal ( root) ; return root; } public void traversal ( TreeNode root) { if ( root == null ) return ; traversal ( root. right) ; sum += root. val; root. val = sum; traversal ( root. left) ; }
}
二、树与回溯
1. 257【二叉树的所有路径】
题目: 给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点代码:
class Solution { List < String > ansList = new ArrayList < > ( ) ; public List < String > binaryTreePaths ( TreeNode root) { if ( root == null ) return new ArrayList < > ( ) ; String path = "" ; traversal ( root, path) ; return ansList; } public void traversal ( TreeNode root, String path) { if ( root. left == null && root. right == null ) { path = path + root. val; ansList. add ( path) ; return ; } String s = path + root. val+ "->" ; if ( root. left != null ) traversal ( root. left, s) ; if ( root. right != null ) traversal ( root. right, s) ; }
}
2. 112【路径总和】
题目: 给你二叉树的根节点 root 和一个表示目标和的整数targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。代码:
class Solution { HashSet < Integer > sums = new HashSet < > ( ) ; public boolean hasPathSum ( TreeNode root, int targetSum) { if ( root == null ) return false ; traversal ( root, 0 ) ; if ( sums. contains ( targetSum) ) { return true ; } return false ; } public void traversal ( TreeNode root, int sum) { if ( root. left== null && root. right== null ) { sum += root. val; sums. add ( sum) ; return ; } sum += root. val; if ( root. left!= null ) traversal ( root. left, sum) ; if ( root. right!= null ) traversal ( root. right, sum) ; }
}
3. 113【路径总和Ⅱ】
题目: 给你二叉树的根节点root和一个整数目标和targetSum,找出所有从根节点到叶子节点路径总和等于给定目标和的路径。代码:
class Solution { List < List < Integer > > ansList = new ArrayList < > ( ) ; List < Integer > path = new LinkedList < > ( ) ; public List < List < Integer > > pathSum ( TreeNode root, int targetSum) { if ( root == null ) return new ArrayList < > ( ) ; traversal ( root, targetSum) ; return ansList; } public void traversal ( TreeNode root, int targetSum) { path. add ( root. val) ; targetSum -= root. val; if ( root. left== null && root. right== null ) { if ( targetSum == 0 ) { ansList. add ( new ArrayList < > ( path) ) ; } return ; } if ( root. left != null ) { traversal ( root. left, targetSum) ; path. removeLast ( ) ; } if ( root. right != null ) { traversal ( root. right, targetSum) ; path. removeLast ( ) ; } }
}
4. 236【二叉树的最近公共祖先】
题目: 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”代码:
class Solution { public TreeNode lowestCommonAncestor ( TreeNode root, TreeNode p, TreeNode q) { if ( root== null || root== p || root== q) { return root; } TreeNode left = lowestCommonAncestor ( root. left, p, q) ; TreeNode right = lowestCommonAncestor ( root. right, p, q) ; if ( left== null && right!= null ) return right; if ( left!= null && right== null ) return left; if ( left== null && right== null ) return null ; return root; }
}
5. 235【二叉搜索树的最近公共祖先】
题目: 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。代码:
class Solution { public TreeNode lowestCommonAncestor ( TreeNode root, TreeNode p, TreeNode q) { if ( root == null ) return null ; if ( root. val> p. val && root. val> q. val) { TreeNode node = lowestCommonAncestor ( root. left, p, q) ; } if ( root. val< p. val && root. val< q. val) { TreeNode node = lowestCommonAncestor ( root. right, p, q) ; } return root; }
}