C# 解决力扣(LeetCode)算法690题 员工的重要性

Problem: 690. 员工的重要性

思路

这个问题可以视作一个典型的图遍历问题。每个员工可以看作图中的一个节点,而员工之间的上下级关系可以看作节点之间的有向边。需要从给定的员工 ID 开始,遍历该员工以及其所有下属节点,计算这些节点的重要度总和。

要解决这个问题,可以选择以下两种常见的图遍历方法之一:

  • 深度优先搜索 (DFS):使用递归或显式栈来遍历图。
  • 广度优先搜索 (BFS):使用队列来逐层遍历图。

在这道题目中,采用 DFS 或 BFS 都可以解决问题。这里将采用 DFS 来解决。

解题过程

1.数据结构优化

  • 首先,需要将给定的员工列表转换为一个便于访问的数据结构。将每个员工对象存储在一个数组中,并通过其 ID 作为索引进行直接访问,使后续查找员工的时间复杂度为 O(1)。

  • 通过遍历 employees 列表,找出 maxId,以此来初始化大小合适的数组 employeeArray,确保了输入数据不连续,也能够正确处理。

2.使用栈进行深度优先搜索

  • 选择用栈来进行深度优先搜索(DFS),这是一个非递归的方法,避免了递归调用可能带来的栈溢出风险。

  • 初始化时,将目标员工的 ID 压入栈中,然后进入循环,直到栈为空为止。

  • 每次从栈中弹出一个员工,计算其重要度,并将其所有下属的 ID 压入栈中。

  • 这种方法可以确保遍历到所有下属,并累加其重要度。

3.使用 Span 优化栈

  • 使用 Span<int> 来分配栈的空间,避免了堆上分配内存的开销,并减少了 GC(垃圾回收)的频率。

  • stackalloc 在栈上分配内存,比普通数组分配更高效,但需要注意栈空间的限制。

4.计算总重要度

  • 每次弹出栈时,累加当前员工的重要度到 totalImportance 中,直到遍历完所有相关员工。

复杂度

  • 时间复杂度: O(n)
  • 空间复杂度: O(n)

Code

internal class Solution
{
    public int GetImportance(IList<Employee> employees, int id)
    {
        int maxId = 0;
        for (int i = 0; i < employees.Count; i++)
        {
            if (employees[i].id > maxId)
                maxId = employees[i].id;
        }
        
        Employee[] employeeArray = new Employee[maxId + 1];
        for (int i = 0; i < employees.Count; i++)
        {
            var emp = employees[i];
            employeeArray[emp.id] = emp;
        }

        int totalImportance = 0;

        Span<int> stack = stackalloc int[employees.Count];
        int stackPointer = 0;

        stack[stackPointer++] = id;

        while (stackPointer > 0)
        {
            int empId = stack[--stackPointer];
            var employee = employeeArray[empId];
            totalImportance += employee.importance;

            var subs = employee.subordinates;
            for (int i = 0; i < subs.Count; i++)
            {
                stack[stackPointer++] = subs[i];
            }
        }

        return totalImportance;
    }
}
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kookoos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值