目录
1.二叉搜索树的最小绝对差
题目:二叉搜索树的最小绝对差
思路:两个思路,其中一个是利用中序迭代遍历或者递归遍历,把结果得到,之后遍历结果中的最小绝对差。第二个思路还是利用以上遍历,但是在遍历过程中就计算结果。
//迭代遍历
func getMinimumDifference(root *TreeNode) int {
//中序的迭代遍历
statck := make([]*TreeNode,0)
res := make([]int,0)
cur := root
for cur !=nil || len(statck) > 0 {
if cur != nil {
statck = append(statck,cur)
cur = cur.Left
}else {
cur = statck[len(statck) - 1]
statck = statck[:len(statck)-1]
res = append(res,cur.Val)
cur = cur.Right
}
}
fmt.Println(len(res))
min := res[1] - res[0]
for i:=0;i<len(res)-1;i++ {
if res[i+1] - res[i] < min {
min = res[i+1] - res[i]
}
}
return min
}
func getMinimumDifference(root *TreeNode) int {
mix := 10000000
pre := 10000000
var Inorder func(root *TreeNode)
Inorder = func(root *TreeNode){
if root == nil{
return
}
Inorder(root.Left)
if mix == 10000000 {
mix -= 1
pre = root.Val
}else {
cha := root.Val - pre
if cha < mix {
mix = cha
}
pre = root.Val
}
Inorder(root.Right)
}
Inorder(root)
return mix
}
2.二叉搜索树中的众数
题目:二叉搜索树中的众数
思路:其实这道题依旧是两个思路,一个是遍历过程中就得到结果,一个是得到遍历结果后去遍历结果得到题目结果。
type result struct {
num int //出现次数
res []int //元素值
}
func findMode(root *TreeNode) []int {
statck := make([]*TreeNode,0)
ans := make([]int,0)
cur := root
for cur != nil || len(statck) > 0 {
if cur != nil {
statck = append(statck,cur)
cur = cur.Left
} else {
cur = statck[len(statck)-1]
statck = statck[:len(statck)-1]
ans = append(ans,cur.Val)
cur = cur.Right
}
}
mode := result{0,[]int{}}
//双指针法查找众数
fast,low := 0,0
for fast < len(ans) {
if ans[fast] == ans[low] {
fast++
}else {
if fast - low > mode.num {
mode.num = fast-low
mode.res = []int{ans[low]}
}else if fast - low == mode.num {
mode.res = append(mode.res,ans[low])
}
low = fast
}
}
if fast - low > mode.num {
mode.num = fast-low
mode.res = []int{ans[low]}
}else if fast - low == mode.num {
mode.res = append(mode.res,ans[low])
}
return mode.res
}
3. 二叉树的最近公共祖先
题目: 二叉树的最近公共祖先
思路:这道题感觉不同于普通的先序遍历或者后序遍历这种,需要我们写递归函数中,一边写,一边思考,细细体会。我整体的思路是:
首先确定递归函数的结束条件,这个应该是三个结束条件。
if root == nil || root == p || root == q {
return root
}
然后写递归逻辑:
先判断左子树能不能找到p或q,在判断右子树能不能找到p或q,之后再根据左右子树的返回结果进行判断,应该往上一层返回什么样的数据。整体代码:
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root == nil || root == p || root == q {
return root
}
l := lowestCommonAncestor(root.Left,p,q)
r := lowestCommonAncestor(root.Right,p,q)
if r != nil && l != nil {
return root
}
if r != nil {
return r
}
return l
}
4.二叉搜索树的最近公共祖先
题目:二叉搜索树的最近公共祖先
思路:这道题其实和上一道题一样,就是多了一个二叉搜索树的性质。
//BSL先序遍历到的第一位于两者之间的即为最近祖先
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root==nil{return nil}
if root.Val>p.Val&&root.Val>q.Val{//当前节点的值大于给定的值,则说明满足条件的在左边
return lowestCommonAncestor(root.Left,p,q)
}else if root.Val<p.Val&&root.Val<q.Val{//当前节点的值小于各点的值,则说明满足条件的在右边
return lowestCommonAncestor(root.Right,p,q)
}else {return root}//当前节点的值在给定值的中间(或者等于),即为最深的祖先
}
5.二叉搜索树中的插入操作
题目:二叉搜索树中的插入操作
思路:这道题就是常规的遍历题,遍历到空节点之后进行插入。
func insertIntoBST(root *TreeNode, val int) *TreeNode {
if root == nil {
return &TreeNode{val,nil,nil}
}
if root.Val > val {
root.Left = insertIntoBST(root.Left,val)
}
if root.Val < val {
root.Right = insertIntoBST(root.Right,val)
}
return root
}
6.删除二叉搜索树中的节点
题目:删除二叉搜索树中的节点
思路:首先利用遍历算法找到要删除的节点,之后执行删除算法,删除算法具体有以下三种情况。
(1)删除节点是叶子节点,直接删除
(2)删除节点只有一棵子树,让其孩子替代该节点
(3)删除节点左右孩子都有,则让其左孩子的最右下的节点,或者右孩子的最左下节点替代该节点。
func deleteNode(root *TreeNode, key int) *TreeNode {
if root == nil {
return nil
}
if root.Val > key {
root.Left = deleteNode(root.Left,key)
}
if root.Val == key {
return delet(root)
}
if root.Val < key {
root.Right = deleteNode(root.Right,key)
}
return root
}
func delet(root *TreeNode) *TreeNode{
//叶子节点,则直接删除
if root.Left == nil && root.Right == nil {
return nil
}
//右子树不为空
if root.Left == nil {
return root.Right
}
//左子树不为空
if root.Right == nil {
return root.Left
}
//左右子树均不为空
ptr := root.Right
pre := ptr
for ptr.Left != nil {
pre = ptr
ptr = ptr.Left
}
root.Val = ptr.Val
//这块不能简单的让其等于nil
if pre != ptr {
pre.Left = ptr.Right
}else {
root.Right = ptr.Right
}
return root
}
7.修剪二叉搜索树
题目:修剪二叉搜索树
思路:
代码:
func trimBST(root *TreeNode, low int, high int) *TreeNode {
if root == nil{
return nil
}
//值比low小,说明root以及root左子树不能要
if root.Val < low {
root = root.Right
root = trimBST(root,low,high)
return root
}
if root.Val > high {
root = root.Left
root = trimBST(root,low,high)
return root
}
//这下说明root是要保留的,但是root的左右子树需要进行修剪
root.Left = trimBST(root.Left,low,high)
root.Right = trimBST(root.Right,low,high)
return root
}