LeetCode 力扣官方题解 | 515. 在每个树行中找最大值

515.在每个树行中找最大值

题目描述
「 Facebook 、亚马逊、三星、Apple 、Shopee 、 云和恩墨、金山在线、Linkedin 、阿里巴巴、华为 」考题

难易度:中等

给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

示例 1 :
请添加图片描述

输入: root = [1,3,2,5,3,null,9]
输出: [1,3,9]

示例 2 :

输入: root = [1,2,3]
输出: [1,3]

提示:

二叉树的节点个数的范围是 [0,10*4]

-231 <= Node.val <= 231 - 1

解决方案

方法一:深度优先搜索

思路与算法

我们用树的「先序遍历」来进行「深度优先搜索」处理,并用 curHeight 来标记遍历到的当前节点的高度。当遍历到 curHeight 高度的节点就判断是否更新该层节点的最大值。

代码

Python3


class Solution:
    def largestValues(self, root: Optional[TreeNode]) -> List[int]:
        ans = []
        def dfs(node: TreeNode, curHeight: int) -> None:
            if node is None:
                return
            if curHeight == len(ans):
                ans.append(node.val)
            else:
                ans[curHeight] = max(ans[curHeight], node.val)
            dfs(node.left, curHeight + 1)
            dfs(node.right, curHeight + 1)
        dfs(root, 0)
        return ans

C++


class Solution {
public:
    void dfs(vector<int>& res, TreeNode* root, int curHeight) {
        if (curHeight == res.size()) {
            res.push_back(root->val);
        } else {
            res[curHeight] = max(res[curHeight], root->val);
        }
        if (root->left) {
            dfs(res, root->left, curHeight + 1);
        }
        if (root->right) {
            dfs(res, root->right, curHeight + 1);
        }
    }

    vector<int> largestValues(TreeNode* root) {
        if (!root) {
            return {};
        }
        vector<int> res;
        dfs(res, root, 0);
        return res;
    }
};

C#

public class Solution {
    public IList<int> LargestValues(TreeNode root) {
        if (root == null) {
            return new List<int>();
        }
        IList<int> res = new List<int>();
        DFS(res, root, 0);
        return res;
    }

    public void DFS(IList<int> res, TreeNode root, int curHeight) {
        if (curHeight == res.Count) {
            res.Add(root.val);
        } else {
            res[curHeight] = Math.Max(res[curHeight], root.val);
        }
        if (root.left != null) {
            DFS(res, root.left, curHeight + 1);
        }
        if (root.right != null) {
            DFS(res, root.right, curHeight + 1);
        }
    }
}

Java


class Solution {
    public List<Integer> largestValues(TreeNode root) {
        if (root == null) {
            return new ArrayList<Integer>();
        }
        List<Integer> res = new ArrayList<Integer>();
        dfs(res, root, 0);
        return res;
    }

    public void dfs(List<Integer> res, TreeNode root, int curHeight) {
        if (curHeight == res.size()) {
            res.add(root.val);
        } else {
            res.set(curHeight, Math.max(res.get(curHeight), root.val));
        }
        if (root.left != null) {
            dfs(res, root.left, curHeight + 1);
        }
        if (root.right != null) {
            dfs(res, root.right, curHeight + 1);
        }
    }
}

C


#define MAX_NODE_SIZE 10001
#define MAX(a, b) ((a) > (b) ? (a) : (b))

void dfs(int *res, int *pos, struct TreeNode* root, int curHeight) {
    if (curHeight == *pos) {
        res[(*pos)++] = root->val;
    } else {
        res[curHeight] = MAX(res[curHeight], root->val);
    }
    if (root->left) {
        dfs(res, pos, root->left, curHeight + 1);
    }
    if (root->right) {
        dfs(res, pos, root->right, curHeight + 1);
    }
} 

int* largestValues(struct TreeNode* root, int* returnSize) {
    if (!root) {
        *returnSize = 0;
        return NULL;
    }
    int *res = (int *)malloc(sizeof(int) * MAX_NODE_SIZE);
    *returnSize = 0;
    dfs(res, returnSize, root, 0);
    return res;
}


JavaScript
var largestValues = function(root) {
    if (!root) {
        return [];
    }
    const res = [];
    const dfs = (res, root, curHeight) => {
        if (curHeight === res.length) {
            res.push(root.val);
        } else {
            res.splice(curHeight, 1, Math.max(res[curHeight], root.val));
        }
        if (root.left) {
            dfs(res, root.left, curHeight + 1);
        }
        if (root.right) {
            dfs(res, root.right, curHeight + 1);
        }
    }
    dfs(res, root, 0);
    return res;
};

Golang

func largestValues(root *TreeNode) (ans []int) {
    var dfs func(*TreeNode, int)
    dfs = func(node *TreeNode, curHeight int) {
        if node == nil {
            return
        }
        if curHeight == len(ans) {
            ans = append(ans, node.Val)
        } else {
            ans[curHeight] = max(ans[curHeight], node.Val)
        }
        dfs(node.Left, curHeight+1)
        dfs(node.Right, curHeight+1)
    }
    dfs(root, 0)
    return
}

func max(a, b int) int {
    if b > a {
        return b
    }
    return a
}

复杂度分析

时间复杂度:O(n) ,其中 n 为二叉树节点个数。二叉树的遍历中每个节点会被访问一次且只会被访问一次。

空间复杂度:O(height) 。其中 height 表示二叉树的高度。递归函数需要栈空间,而栈空间取决于递归的深度,因此空间复杂度等价于二叉树的高度。

方法二:广度优先搜索

思路与算法

我们也可以用「广度优先搜索」的方法来解决这道题目。「广度优先搜索」中的队列里存放的是「当前层的所有节点」。

每次拓展下一层的时候,不同于「广度优先搜索」的每次只从队列里拿出一个节点,我们把当前队列中的全部节点拿出来进行拓展,这样能保证每次拓展完的时候队列里存放的是下一层的所有节点,即我们是一层一层地进行拓展,然后每一层我们用 maxVal 来标记该层节点的最大值。

当该层全部节点都处理完后,maxVal 就是该层全部节点中的最大值。

代码

Python3

class Solution:
    def largestValues(self, root: Optional[TreeNode]) -> List[int]:
        if root is None:
            return []
        ans = []
        q = [root]
        while q:
            maxVal = -inf
            tmp = q
            q = []
            for node in tmp:
                maxVal = max(maxVal, node.val)
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)
            ans.append(maxVal)
        return ans

C++


class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        if (!root) {
            return {};
        }
        vector<int> res;
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            int len = q.size();
            int maxVal = INT_MIN;
            while (len > 0) {
                len--;
                auto t = q.front();
                q.pop();
                maxVal = max(maxVal, t->val);
                if (t->left) {
                    q.push(t->left);
                }
                if (t->right) {
                    q.push(t->right);
                }
            }
            res.push_back(maxVal);
        }
        return res;
    }
};

Java


class Solution {
    public List<Integer> largestValues(TreeNode root) {
        if (root == null) {
            return new ArrayList<Integer>();
        }
        List<Integer> res = new ArrayList<Integer>();
        Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int len = queue.size();
            int maxVal = Integer.MIN_VALUE;
            while (len > 0) {
                len--;
                TreeNode t = queue.poll();
                maxVal = Math.max(maxVal, t.val);
                if (t.left != null) {
                    queue.offer(t.left);
                }
                if (t.right != null) {
                    queue.offer(t.right);
                }
            }
            res.add(maxVal);
        }
        return res;
    }
}

C#

public class Solution {
    public IList<int> LargestValues(TreeNode root) {
        if (root == null) {
            return new List<int>();
        }
        IList<int> res = new List<int>();
        Queue<TreeNode> queue = new Queue<TreeNode>();
        queue.Enqueue(root);
        while (queue.Count > 0) {
            int len = queue.Count;
            int maxVal = int.MinValue;
            while (len > 0) {
                len--;
                TreeNode t = queue.Dequeue();
                maxVal = Math.Max(maxVal, t.val);
                if (t.left != null) {
                    queue.Enqueue(t.left);
                }
                if (t.right != null) {
                    queue.Enqueue(t.right);
                }
            }
            res.Add(maxVal);
        }
        return res;
    }
}

C

#define MAX_NODE_SIZE 10001
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int* largestValues(struct TreeNode* root, int* returnSize) {
    if (!root) {
        *returnSize = 0;
        return NULL;
    }
    int *res = (int *)malloc(sizeof(int) * MAX_NODE_SIZE);
    int pos = 0;
    struct TreeNode **queue = (struct TreeNode *)malloc(sizeof(struct TreeNode *) * MAX_NODE_SIZE);
    int head = 0, tail = 0;
    queue[tail++] = root;
    while (head != tail) {
        int len = tail - head;
        int maxVal = INT_MIN;
        while (len > 0) {
            len--;
            struct TreeNode *node = queue[head++];
            maxVal = MAX(maxVal, node->val);
            if (node->left) {
                queue[tail++] = node->left;
            }
            if (node->right) {
                queue[tail++] = node->right;
            }
        }
        res[pos++] = maxVal;
    }
    *returnSize = pos;
    free(queue);
    return res;
}

JavaScript

var largestValues = function(root) {
    if (!root) {
        return [];
    }
    const res = [];
    const queue = [root];
    while (queue.length) {
        let len = queue.length;
        let maxVal = -Number.MAX_VALUE;
        while (len > 0) {
            len--;
            const t = queue.shift();
            maxVal = Math.max(maxVal, t.val);
            if (t.left) {
                queue.push(t.left);
            }
            if (t.right) {
                queue.push(t.right);
            }
        }
        res.push(maxVal);
    }
    return res;
};

Golang

func largestValues(root *TreeNode) (ans []int) {
    if root == nil {
        return
    }
    q := []*TreeNode{root}
    for len(q) > 0 {
        maxVal := math.MinInt32
        tmp := q
        q = nil
        for _, node := range tmp {
            maxVal = max(maxVal, node.Val)
            if node.Left != nil {
                q = append(q, node.Left)
            }
            if node.Right != nil {
                q = append(q, node.Right)
            }
        }
        ans = append(ans, maxVal)
    }
    return
}

func max(a, b int) int {
    if b > a {
        return b
    }
    return a
}

复杂度分析

时间复杂度:O(n) ,其中 n 为二叉树节点个数,每一个节点仅会进出队列一次。

空间复杂度:O(n) ,存储二叉树节点的空间开销。

获取更多详情:LeetCode 力扣官方题解 | 515. 在每个树行中找最大值

编辑/版式:pingping

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值