목차
235. 이진 검색 트리의 가장 가까운 공통 조상
이진 트리의 가장 가까운 공통 조상과 비교할 때 이 질문은 이진 검색 트리의 특성을 사용할 수 있기 때문에 더 간단합니다.
주제 링크/기사 설명: 코드 카프리스
솔루션 아이디어:
1. 재귀 구현
반복법과 재귀법의 원리는 같지만 사실 이 반복법의 본질은 재귀법이라고 생각하지만 단계가 다릅니다! ! !
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while(root != null){
if(root.val > p.val && root.val > q.val){
TreeNode left = lowestCommonAncestor(root.left,p,q);
if(left != null) return left;
}else if(root.val < p.val && root.val < q.val){
TreeNode right = lowestCommonAncestor(root.right,p,q);
if(right != null) return right;
}else{
return root;
}
}
return null;
}
}
2. 반복적 방법의 구현
반복법과 재귀법의 원리는 같지만 사실 이 반복법의 본질은 재귀법이라고 생각하지만 단계가 다릅니다! ! !
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while(root != null){
if(root.val > p.val && root.val > q.val){
TreeNode left = lowestCommonAncestor(root.left,p,q);
if(left != null) return left;
}else if(root.val < p.val && root.val < q.val){
TreeNode right = lowestCommonAncestor(root.right,p,q);
if(right != null) return right;
}else{
return root;
}
}
return null;
}
}
701. 이진 검색 트리의 삽입 연산(재귀적 구현)
이 문제는 생각보다 간단합니다 직접 해보는 방법을 생각해보고 동영상 설명을 보시면 이 문제가 비교적 간단한 이유를 알 수 있을 것입니다.
주제 링크/기사 설명: 코드 카프리스
솔루션 아이디어:
Ka Ge의 비디오 설명을 더 들어보세요! ! ! 이진 트리에서의 삽입 연산은 이진 트리를 구성하는 것으로, 리프 노드에서 삽입하고자 하는 노드를 찾을 수 있어야 하며, 특성에 따라 현재 노드의 val 값과 주어진 val 값을 비교할 수 있습니다. 이진 검색 트리의 왼쪽 하위 트리에 있는지 여부를 직접 판단하면 오른쪽 하위 트리가 삽입됩니다! ! ! 마지막으로 루트 노드로 직접 돌아갑니다! ! ! Ka Ge의 설명을 듣기 전에는 그냥 엉망진창이었지만 첫 느낌은 매우 복잡했고 다양한 삽입 방법 등이 있었습니다! ! ! Ka Ge의 비디오 설명을들은 후에도 생각은 여전히 명료합니다 더 많이 듣고 더 많이보고 더 스 와이프하여 마음을 열어야합니다! ! ! 비과학적 수업을 위한 코드 변환은 실제로 약간 고통스럽고 이전에 훈련되지 않은 사고 방식을 정말 전복합니다! ! ! 어서 해봐요! ! !
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
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); //直接根据二叉搜索树的特性比较当前节点的val值和给定的val,直接判断在其左子树还是右子树进行插入操作
}else if(root.val < val){
root.right = insertIntoBST(root.right,val); //直接根据二叉搜索树的特性比较当前节点的val值和给定的val,直接判断在其左子树还是右子树进行插入操作
}
return root;
}
}
作者:vansven-h
链接:https://leetcode.cn/problems/insert-into-a-binary-search-tree/solution/701er-cha-sou-suo-shu-zhong-de-cha-ru-ca-fj39/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
450. 이진 검색 트리에서 노드 삭제(재귀 구현)
삽입 작업과 비교할 때 이 질문은 더 어렵고 트리의 구조를 변경해야 합니다.
주제 링크/기사 설명: 코드 카프리스
솔루션 아이디어:
그 주된 이유는 노드를 삭제하는 상황이 5가지가 있고, 상황에 따라 하나씩 처리해야 하기 때문인데, 구체적인 5가지 상황은 아래 주석 코드를 참고하세요! ! ! 내가 하고 싶은 말은 일단 스 와이프하면 더 많이보고 Kage의 비디오를 듣고 더 스 와이프해야한다는 것입니다. 방법론을 마스터해야만 자신의 바퀴를 만들 수 있는 자본을 가질 수 있습니다. 이것들은 기본 알고리즘이며, 어떻게 얘기해야할지 모르겠어 고급 지식! ! !
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
//第二步:确定终止条件,当找到五种不同情况的节点需要删除时,此时就是遍历到的节点就是终止条件,需要及时对找到的节点进行处理才行
if(root == null) return null; //第一种情况:没找到要删除的节点,直接返回null值即可
else if(root.val == key){ //以下四种情况都是在找到要删除节点的情况下进行讨论的
if(root.left == null && root.right == null) return null; //第二种情况:删除的时叶子节点
else if(root.left != null && root.right == null) return root.left; //第三种情况:删除左不为空,右为空的节点
else if(root.left == null && root.right != null) return root.right;//第四种情况:删除左为空,右不为空的节点
else{
TreeNode current = root.right; //第五种情况:删除左不为空,右不为空的节点,根据二叉搜索树的特性,需要一直搜索右子树的左节点,一直其叶节点进行插入
while( current.left != null){
current = current.left;
}
current.left = root.left;
return root.right;
}
}
//第三步:确定单层处理逻辑,根据二叉树的搜索特性,直接比较当前遍历节点的val值和key值,直接判断在其左子树还是右子树进行删除节点操作
if(root.val > key) root.left = deleteNode(root.left,key);
else if(root.val < key) root.right = deleteNode(root.right,key);
return root;
}
}