代码随想录第二十一天

Leetcode 530. 二叉搜索树的最小绝对差

题目链接: 二叉搜索树的最小绝对差
自己的思路:和验证二叉搜索树一样的思路!可以求每个相邻节点的差值的绝对值,然后和之前的差值的绝对值进行比较,取最小的为新的res;递归三部曲:1、传入参数:当前节点;2、终止条件:如果当前节点为空,直接返回;3、单层递归逻辑:中序遍历!!因为中序遍历可以保证是递增的,这样就不会跳着比较,所以先递归左子树,然后中节点和前一个节点求差值的绝对值和res比较,取最小值为res,然后再定义新的pre,再进行右子树的遍历即可!!!

正确思路:

代码:

class Solution {
    int res = Integer.MAX_VALUE;
    TreeNode pre;
    public int getMinimumDifference(TreeNode root) {
        if (root==null) return 0;
        getmin(root);
        return res;
    }
    
    public void getmin(TreeNode root){
        if (root==null) return;
        //左递归
        getmin(root.left);
        //求上一个节点和此节点的最小值和之前的差进行比较
        if (pre!=null){
            res = Math.min(res,Math.abs(pre.val-root.val));
        }
        //重新表示上一个节点
        pre = root;
        //右递归
        getmin(root.right);
    }
}

复杂度分析
时间复杂度: O ( n ) \mathcal{O}(n) O(n)
空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)

Leetcode 501. 二叉搜索树中的众数

题目链接: 二叉搜索树中的众数
自己的思路:没想到!!!!

正确思路:比较笨的方法是遍历两次二叉树,然后找其中最大的值就可以;但是这里是使用了一点代码技巧来处理这个问题,所以使用一次遍历就可以;具体的思路为:二叉搜索树一定是中序遍历!!!!这样可以保证有序,主要是处理中的逻辑,我们可以定义三个变量,count用于存储当前结点的值出现的次数,maxcount用于存储出现的最多的结点出现的次数,pre存储上一个节点;首先是计数阶段:当pre是空的时候,那也就是说node现在是出于叶子节点,记录它的count值为1,当pre的结点值等于node的结点值的时候,说明出现了相同的节点值,则count++,当pre的结点值不等于node的结点值时,说明出现了不同的节点值,重置count为1;然后是加入结果阶段:当count==maxcount的时候,说明当前的次数和最大的次数相同,当前结点值加入到结果集中,如果count>maxcount的时候,说明之前的maxcount并不是全局的最大,所以把之前的res中的所有元素清空,然后再加入新的结果,并且把maxcount赋值为count;递归三部曲:1、传入参数:当前节点;2、终止条件:当当前节点为空的时候,返回;3、单层逻辑:先左递归,然后处理中间节点,然后右递归!!!

代码:

class Solution {
    List<Integer> res = new ArrayList<>();
    int count = 0;
    int maxcount = 0;
    TreeNode pre;
    public int[] findMode(TreeNode root) {
        addMode(root);
        int [] re = new int[res.size()];
        for (int i =0;i<re.length;i++){
            re[i] = res.get(i);
        }
        return re;
    }
    public void addMode(TreeNode node){
        if (node==null) return;
        addMode(node.left);

        //计数阶段
        if (pre==null) count=1;
        else if (pre.val==node.val){
            count++;
        }
        else count=1;

        //加结果阶段
        if (count>maxcount){
            maxcount = count;
            res.clear();
            res.add(node.val);
        }else if (count==maxcount){
            res.add(node.val);
        }
        pre = node;
        addMode(node.right);
    }
}

复杂度分析
时间复杂度: O ( n ) \mathcal{O}(n) O(n)
空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)

Leetcode 236. 二叉树的最近公共祖先

题目链接: 二叉树的最近公共祖先
自己的思路:没想到!!!

正确思路:主要是遍历顺序,使用后序遍历出来,自底向上地返回;递归三部曲:1、传入参数:当前结点、结点p、结点q;2、终止条件:当当前结点是空或者p和q时,直接返回当前结点即可,因为没有比这个更深的结点了;3、单层递归逻辑:先左右递归左右子树查找左右子树分别对p和q的最近公共祖先,得到left和right,如果两个都为空,说明没找到,直接返回null,如果其中一个不为空,另一个为空,说明不为空的那个为最近公共祖先,如果两个都不为空,则当前节点为最近公共祖先!!!
代码:

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //如果当前结点就是空或者p和q的话,直接返回当前结点
        if (root==null||root==p||root==q){
            return root;
        }
        //递归左右子树
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        //如果左右两边都没有,直接返回null
        if (left==null&&right==null) return null;
        //左边有返回左边,右边有返回右边
        if (left==null||right==null){
            return left==null?right:left;
        }
        //左右两边都有返回当前结点
        return root;
    }
}

复杂度分析
时间复杂度: O ( n ) \mathcal{O}(n) O(n)
空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二十二算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值