首页 > 其他分享 >代码随想录day20 || 235 二叉搜索树最近公共祖先,701 二叉搜索树插入,450,二叉搜索树删除节点

代码随想录day20 || 235 二叉搜索树最近公共祖先,701 二叉搜索树插入,450,二叉搜索树删除节点

时间:2024-08-05 11:51:05浏览次数:5  
标签:Right cur nil 随想录 二叉 搜索 Val root Left

235 二叉搜索树最近公共祖先

unc lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
	// 本题相较于普通二叉树寻找最近公共祖先加了题设条件二叉搜索树,所以使用二叉搜索树特性
	// 如果root 大于两个目标节点,那么目标都在root左子树
	// 如果root 小于两个目标节点,那么目标都是root右子树
	// 如果root == 任何一个目标,或者root大于一个小于另一个目标,那么root就是最近公共祖先
	if root == nil {
		return nil
	}

	// 使用后序traversal
	var left, right *TreeNode
	if root.Val >= p.Val && root.Val <= q.Val ||
		root.Val <= p.Val && root.Val >= q.Val {
		return root
	}

	if root.Val > p.Val && root.Val > q.Val {
		left = lowestCommonAncestor(root.Left, p, q)
	}
	if root.Val < p.Val && root.Val < q.Val {
		right = lowestCommonAncestor(root.Right, p, q)
	}

	if left != nil {
		return left
	}
	if right != nil {
		return right
	}

	return nil
}


func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
	// 迭代法
	if root == nil {
		return nil
	}

	// 使用后序traversal
	cur := root
	for (cur != nil) {
		if cur.Val > p.Val && cur.Val > q.Val {
			cur = cur.Left
		}else if cur.Val < p.Val && cur.Val < q.Val {
			cur = cur.Right
		}else  {
			return cur
		}
	}
	return nil
}

701 二叉搜索树插入操作

func insertIntoBST(root *TreeNode, val int) *TreeNode {
	// 思路1, 任何插入的节点都可以插入成为叶子节点中,本题并没有要求平衡,所以随意
	node := &TreeNode{val, nil, nil}
	if root == nil {
		return node
	}
	insert(root, node)
	return root
}

func insert(root, node *TreeNode) {
	if root.Val > node.Val {
		if root.Left == nil {
			root.Left = node
		}else {
			insert(root.Left, node)
		}
	}

	if root.Val < node.Val {
		if root.Right == nil {
			root.Right = node
		} else {
			insert(root.Right, node)
		}
	}
}

450 二叉搜索树删除节点

func deleteNode(root *TreeNode, key int) *TreeNode {
	// 歪门邪道思路,遍历二叉树,然后针对每一个节点插入
	if root == nil {
		return nil
	}

	var newRoot *TreeNode
	q := list.New()
	q.PushBack(root)
	for q.Len() > 0 {
		node := q.Remove(q.Front()).(*TreeNode)
		if node.Val != key {
			newRoot = insert(newRoot, node.Val)
		}
		if node.Left != nil {
			q.PushBack(node.Left)
		}
		if node.Right != nil {
			q.PushBack(node.Right)
		}
	}
	return newRoot
}

//func inorder (root *TreeNode, res *[]int){
//	if root == nil {
//		return
//	}
//	inorder(root.Left, res)
//	*res = append(*res, root.Val)
//	inorder(root.Right, res)
//}

func insert (root *TreeNode, val int) *TreeNode{
	if root == nil {
		root = &TreeNode{val, nil, nil}
		return root
	}
	if root.Val > val {
		if root.Left == nil {
			root.Left = &TreeNode{val, nil, nil}
		}else {
			insert(root.Left, val)
		}
	}

	if root.Val < val {
		if root.Right == nil {
			root.Right = &TreeNode{val, nil, nil}
		}else {
			insert(root.Right, val )
		}
	}
	return root
}

// 删除叶子节点:直接删除该节点。
// 删除只有一个子节点的节点:将该节点的父节点指向该节点的子节点。
// 删除有两个子节点的节点:找到该节点的中序后继或中序前驱,用后继或前驱替换该节点,然后删除后继或前驱。


func deleteNode(root *TreeNode, key int) *TreeNode {
	if root == nil {
		return nil
	}
	if root.Left == nil && root.Right == nil && root.Val == key{
		return nil
	}

	// Find the node to be deleted and its parent.
	var pre *TreeNode
	cur := root
	for cur != nil && cur.Val != key{
		pre = cur
		if key < cur.Val {
			cur = cur.Left
		} else {
			cur = cur.Right
		}
	}
	// If the node to be deleted is not found, return the original root.
	if cur == nil {
		return root
	}

	// Case 1: Node to be deleted is a leaf node.
	if cur.Left == nil && cur.Right == nil {
		if pre == nil {
			root = nil
		}else if pre.Left == cur {
			pre.Left = nil
		}else {
			pre.Right = nil
		}
		return root
	}

	// Case 2: Node to be deleted has only one child.
	if cur.Left != nil && cur.Right == nil {
		if pre == nil {
			root = cur.Left
		}else if pre.Left == cur {
			pre.Left = cur.Left
		}else {
			pre.Right = cur.Left
		}
		return root
	}
	if cur.Right != nil  && cur.Left == nil{
		if pre == nil {
			root = cur.Right
		}else if pre.Left == cur {
			pre.Left = cur.Right
		}else {
			pre.Right = cur.Right
		}
		return root
	}

	// Case 3: Node to be deleted has two children.
	// Find the inorder successor (smallest in the right subtree).
	successorParent := cur
	successor := cur.Right
	for successor.Left != nil {
		successorParent = successor
		successor = successor.Left
	}

	// Replace node's value with successor's value.
	cur.Val = successor.Val

	// Delete the successor node.
	if successorParent.Left == successor {
		successorParent.Left = successor.Right
	} else {
		successorParent.Right = successor.Right
	}

	return root
}


标签:Right,cur,nil,随想录,二叉,搜索,Val,root,Left
From: https://www.cnblogs.com/zhougongjin55/p/18342940

相关文章

  • 图片搜索网站,有大量高清图片,避免版权纠纷
    一、简介1、一个图片搜索网站,所有图片均遵循CC0协议,用户可以免费用于商业用途而无需标注来源。网站上有大量高清图片,基本可以满足用户的各种需求,同时避免了法律风险。提供强大的筛选功能,用户可以按图片方向、尺寸和颜色筛选,还会推荐相似内容。用户可以点赞、收藏和分享查看......
  • 如何创建搜索框
    文章目录1.概念介绍2.使用方法3.代码与效果3.1示例代码3.2运行效果4.内容总结我们在上一章回中介绍了"Material3中的IconButton"相关的内容,本章回中将介绍SearchBar组件.闲话休提,让我们一起TalkFlutter吧。1.概念介绍我们在本章回中介绍的SearchBar是指......
  • 代码随想录Day4
    24.两两交换链表中的节点给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。示例1:输入:head=[1,2,3,4]输出:[2,1,4,3]示例2:输入:head=[]输出:[]示例3:输入:head=[1]输出:[1]提示:链表......
  • 代码随想录二刷字符串
    代码随想录二刷字符串看leetcode这样一道题目:这道题若是用python库函数直接就秒了。但是那这道题就失去了本身的意义。题目注意事项中也说了输入字符串S可能存在前导空格、尾随空格或者单词间的多个空格。所以首先是对字符串处理。去除其中的空格。这与之前去除数组中去除特定......
  • 算法力扣刷题总结篇 ——【五】二叉树章节
    前言从记录三十五【二叉树基础和递归遍历】到记录六十二【538.把二叉搜索树转换为累加树】28篇文章都是二叉树的章节。所以总结的任务量有点大啊。但还是要做的。完成之后,开启新章节……继续。一、题目回顾1-5:遍历方式模版题。6-14:确定遍历顺序。后序居多——先统......
  • 数据结构之《二叉树》(中)
    在数据结构之《二叉树》(上)中学习了树的相关概念,还了解的树中的二叉树的顺序结构和链式结构,在本篇中我们将重点学习二叉树中的堆的相关概念与性质,同时试着实现堆中的相关方法,一起加油吧!1.实现顺序结构二叉树在实现顺序结构的二叉树中通常把堆使用顺序结构的数组来存储,因......
  • 代码随想录算法训练营day03|203.移除链表元素,707.设计链表,206.反转链表
    203.移除链表元素题目链接:https://leetcode.cn/problems/remove-linked-list-elements/description/我的代码(分头节点和中间节点两种情况操作):/***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNode*next;*ListNode():val......
  • 代码随想录 day 44 最长公共子序列 | 不相交的线 | 最大子序和 | 判断子序列
    最长公共子序列最长公共子序列解题思路本题dp数组的含义是最长公共序列,而后同时遍历两个字符串,遇到相同的字母是公共子序列+1,否则取两个字符串的公共子序列中较长的一个。知识点动态规划,子序列心得没有想到比较两个字符串的公共子序列。我自己是遇到相同字母时将所有后续的......
  • 动态规划与搜索练习
    这是我搜集到的一些动态规划和搜索的练习题搜索小练习动态规划小练习祝你CSP拿到\(^{一等奖}_{一等奖}\)!这是解析动态规划一、双子序列最大和由于两个子序列不重叠,显然的这两个子序列之间一定有一个断点。要求两个子序列之和最大值,可以枚举断点的位置,对比每个断点下左序......
  • day018二叉树
    530.二叉树的最小绝对差给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。差值是一个正数,其数值等于两值之差的绝对值。 思路:此题与昨天的验证二叉搜索树很像,同样是中序遍历将二叉树节点按照顺序加入到动态数组中,随后遍历动态数组,维护一......