LeetCode.671.二叉树中第二小的节点之刷算法新感悟

0 前言

刷算法打卡第五天,今天来了一个简单题,但是我记录了它。因为这个题对于我值得复盘,也有可以沉淀的一些编程细节。
今天非常顺利的完成了算法。根据昨天完成算法的收获来完成今天的算法,即分析问题->联系所学基础知识转化问题。
在这里插入图片描述

一、问题分析

二叉树是一个递归结构,每次取最小数,即最上层一定是最小的数。
即一个节点数只要比另一个节点数小,那么这个节点数将小于另一个节点下所有的节点数。
所以最小的数一定在root节点,而第二节点数在那里呐?
第二节点是第一节点的手下败将,所以第二节点就是每一个跟节点数为最小的兄弟节点。

二、转换问题

所以把问题转化为遍历最小节点数下的子树直到叶子节点。

三、代码分析

1、ArrayList

特殊的层次遍历就要涉及到队列,我们这里用ArrayList作为满足上述元素条件的存储器。用add(node)和remove(0)方法来完成进队和出队的限定。

List<TreeNode> queen = new ArrayList<>();
        queen.add(root);

2、特殊的层次遍历

在层次遍历时,顺便找出第二小节点。

while (queen.size() != 0) {
            TreeNode node = queen.get(0);
            if (node.left != null) {
                if (node.left.val == min) {
                    queen.add(node.left);
                    second=second==min?node.right.val:node.right.val==min?second:second<node.right.val?second:node.right.val;
                }
                if(node.right.val == min)
                    {
                    queen.add(node.right);
                    second=second==min?node.left.val:node.left.val==min?second:second<node.left.val?second:node.left.val;
                }
            }
            queen.remove(0);
        }

3、return

可能存在所有元素一样大的情况,前面的初始化+这里的判断完成最终的返回。

second=second==min?-1:second;
return second;

四、完整算法

1、源代码

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

    public int findSecondMinimumValue(TreeNode root) {
        /*  分析问题
        二叉树是一个递归结构,每次取最小数,即最上层一定是最小的数。
        即一个节点数只要比另一个节点数小,那么这个节点数将小于另一个节点下所有的节点数。
        所以最小的数一定在root节点,而第二节点数在那里呐?
        第二节点是第一节点的手下败将,所以第二节点就是每一个跟节点数为最小的兄弟节点。
            转化问题
        所以把问题转化为遍历最小节点数下的子树直到叶子节点。
        */
        //1. 通过使用队列的方式去特殊的层次遍历,将等于root节点的进入队列,用一个值去存第二小的数(用判断的方式)
        int min = root.val;
        int second = root.val;
        if (root.left != null) {
            second = root.left.val > root.right.val ? root.left.val : root.right.val;
        }
        List<TreeNode> queen = new ArrayList<>();
        queen.add(root);
        while (queen.size() != 0) {
            TreeNode node = queen.get(0);
            if (node.left != null) {
                if (node.left.val == min) {
                    queen.add(node.left);
                    second=second==min?node.right.val:node.right.val==min?second:second<node.right.val?second:node.right.val;
                }
                if(node.right.val == min)
                    {
                    queen.add(node.right);
                    second=second==min?node.left.val:node.left.val==min?second:second<node.left.val?second:node.left.val;
                }
            }
            queen.remove(0);
        }
        second=second==min?-1:second;
        return second;
    }

2、算法评估

时间复杂度:O(n),n为树所有节点数。
空间复杂度:O(m),m为该特殊二叉树的宽度。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值