코드랜덤기록 알고리즘 훈련 22일째|235. 이진탐색 트리의 가장 가까운 공통 조상, 701. 이진탐색 트리의 삽입 연산, 450. 이진탐색 트리의 노드 삭제

목차

235. 이진 검색 트리의 가장 가까운 공통 조상

1. 재귀 구현

2. 반복적 방법의 구현

 701. 이진 검색 트리의 삽입 연산(재귀적 구현)

450. 이진 검색 트리에서 노드 삭제(재귀 구현)


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;
    }
}

추천

출처blog.csdn.net/tore007/article/details/130628721