刷力扣记录

今天的力扣记录是代码随想录的二叉搜索树修改、删减等题目和双指针的反转单词、调整数组顺序等题目。二叉搜索树确实很有规律,如果是中序,就可以直接从小到大有序排列,所以可以直接走中序,记录好前一个节点或者前一个节点数值。

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

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)从这个可以看到,在p和q里找公共祖先,那肯定是判断根节点和pq之间的相对大小,如果都在左侧,那么直接递归到左子树去判断;同理,都在右侧,直接去右子树判断,那么一左一右就肯定找到了,根节点就是最近公共祖先。

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == p || root == q || root == null) return root;
        //二叉搜索树有个神奇的特性
        //都在左,递归左边,都在右,递归右边
        //一左一右,返回中间
        if(root.val > p.val && root.val > q.val){
            TreeNode left = lowestCommonAncestor(root.left, p, q);
            if(left != null) return left;
        }
        if(root.val < q.val && root.val < p.val){
            TreeNode right = lowestCommonAncestor(root.right, p, q);
            if(right != null) return right;
        }

        return root;
    }
}

701.二叉搜索树中的插入操作

这个二叉搜索树的插入,那直接走到左子树或者右子树的叶子节点,那凑左边或者右边就行。这个肯定是递归操作,如果大于就走左边去递归,但是要用root去接着;如果小于就是右边递归,用root接着;关键是中间的跟节点肯定是插入操作,看到空再操做。

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null){
            TreeNode tmp = new TreeNode(val);
            return tmp;
        }
        //遍历
        if(root.val > val){
            root.left = insertIntoBST(root.left, val);
        }
        if(root.val < val){
            root.right = insertIntoBST(root.right, val);
        }
        return root;
    }
}

450.删除二叉搜索树中的节点

删除那肯定也是要判断,如果value对上了,就是可以判断如何删除;不对,就是左右递归。删除的逻辑就是如果都空了,返回就行,如果是左右有一个为空,返回另一个就行,两个都不为空,那不能简单凑在一起,需要左右子树的一支走到空,然后把另一只放到尾上,返回适合的节点。

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 null;
            }
            if(root.left == null){
                return root.right;
            }
            if(root.right == null){
                return root.left;
            }
            if(root.left != null && root.right != null){
                // root.left = root.right.left;
                //正儿八经的右节点走到底,
                //得把右子树的左节点走到空,总会有空的
                TreeNode tmp = root.right;
                while(tmp.left != null){
                    tmp = tmp.left;
                }
                tmp.left = root.left;
                return root.right;
            }
        }
        if(root.val > key){
            root.left = deleteNode(root.left, key);
        }
        if(root.val < key){
            root.right = deleteNode(root.right, key);
        }
        return root;
    }
}

669. 修剪二叉搜索树

这个是在low和high的节点都保存下来,这个肯定是先序就可以操作,关键是中节点是怎么操作,如果是中节点大于high,那么递归左子树(右子树没了);反过来依然,然后中节点搞完,可以递归左右节点,直接接住就行。

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if(root == null) return null;
        if(root.val > high || root.val < low){
            //去除的逻辑
            if(root.val > high){
                //条件一:左右都空
                if(root.left == null) return null;
                if(root.left != null){
                    return trimBST(root.left, low, high);
                }
            }
            if(root.val < low){
                if(root.right == null) return null;
                if(root.right != null){
                    return trimBST(root.right, low, high);
                }
            }
        }
        root.left = trimBST(root.left, low, high);
        root.right = trimBST(root.right, low, high);
        return root;
    }
}

538.把二叉搜索树转换为累加树

这个肯定就是反过来右中左这个反中序就行,关键是要保存前面的值,这个采用全局变量就行。

class Solution {
    int pre = 0;
    public TreeNode convertBST(TreeNode root) {
        if(root == null) return root;
        TreeNode right = convertBST(root.right);
        root.val += pre;
        pre = root.val;
        TreeNode left = convertBST(root.left);
        return root;

    }
}

剑指 Offer 58 - I. 翻转单词顺序

这个感觉不像中等题目,但是思路是很明确的,直接搞,先去中间的和左右多余的空格,接着反转。

class Solution {
    public String reverseWords(String s) {
        StringBuilder sb = trimSpaces(s);

        // 翻转字符串
        reverse(sb, 0, sb.length() - 1);

        // 翻转每个单词
        reverseEachWord(sb);

        return sb.toString();
    }

    public StringBuilder trimSpaces(String s) {
        int left = 0, right = s.length() - 1;
        // 去掉字符串开头的空白字符
        while (left <= right && s.charAt(left) == ' ') {
            ++left;
        }

        // 去掉字符串末尾的空白字符
        while (left <= right && s.charAt(right) == ' ') {
            --right;
        }

        // 将字符串间多余的空白字符去除
        StringBuilder sb = new StringBuilder();
        while (left <= right) {
            char c = s.charAt(left);

            if (c != ' ') {
                sb.append(c);
            } else if (sb.charAt(sb.length() - 1) != ' ') {
                sb.append(c);
            }

            ++left;
        }
        return sb;
    }

    public void reverse(StringBuilder sb, int left, int right) {
        while (left < right) {
            char tmp = sb.charAt(left);
            sb.setCharAt(left++, sb.charAt(right));
            sb.setCharAt(right--, tmp);
        }
    }

    public void reverseEachWord(StringBuilder sb) {
        int n = sb.length();
        int start = 0, end = 0;

        while (start < n) {
            // 循环至单词的末尾
            while (end < n && sb.charAt(end) != ' ') {
                ++end;
            }
            // 翻转单词
            reverse(sb, start, end - 1);
            // 更新start,去找下一个单词
            start = end + 1;
            ++end;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值