【华为机试题】(2022.4.6)服务启动

服务启动

题目

有若干个连续编号的服务(编号从0开始),服务间有依赖关系,启动一个指定服务,请判断该服务是否可以成功启动,并输出依赖的前置服务编号(依赖关系是可传递的,比如服务2依赖于服务1,服务1依赖于服务0,那么服务2依赖于服务1和服务0)


输入要求

第一行输入为N,N为服务的总个数(1 ≤N ≤5000);第二行输入为M,M为指定启动服务的编号(0 ≤M ≤5000)接下来的N行,是从编号0服务~编号N-1服务的服务依赖表,每一行第一个数字是该服务依赖的服务个数T(0 ≤T ≤ 5000),后面T个数字分别是对应的依赖服务编号

输出要求

为了避免不同算法的服务加载顺序不同,请按服务编号从小到大依次输出所有前置服务的编号,不包括指定启动的服务编号自身。如果没有依赖的前置服务则输出null.如果服务无法启动(出现循环依赖,则服务无法启动,示例2为最简单的循环依赖)或其他异常,则输出-1。

示例1

输入

4
2
0
1,0
1,1
2,01

输出

0,1

解释

第一行4-共有四个服务,编号从0-3
第二行2,指启动编号为2的服务
第三行开始,为服务依赖关系表(从编号为0的服务开始)
第三行,0,表明服务0,没有依赖的前置服务(依赖个数为0)
第四行,1,0,表明服务1,依赖1个前置服务,依赖的前置服务编号为0
第五行,1,1,表明服务2,依赖1个前置服务,依赖的前置服务编号为1
第六行,2,0,1表明服务3,依赖2个前置服务,依赖的前置服务编号为01
分析,服务启动顺序为0,1,2,可成功启动服务2,输出0,1

示例2

输入

2
1
1,1
1,0

输出

-1

思路

本题考察广度优先遍历, 先使用嵌套List>对服务前置依赖编号进行统计 ,再利用队列和集合从启动编号开始进行广度优先遍历,遍历过程将结果加入结果集合,最后进行输出(由于输出格式问题,最后一个数需要单独输出)。

代码实现

java代码:

public class StartService {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = Integer.valueOf(sc.nextLine());
        int m = Integer.valueOf(sc.nextLine());

        List<List<Integer>> map = new ArrayList<>(n);  //<编号,<前置依赖>>
        for (int i = 0; i < n; i++) {
            map.add(new ArrayList<>());
        }
        for (int i = 0; i < n; i++) {
            String[] split = sc.nextLine().split(",");
            for (int j = 1; j < split.length; j++) {
                map.get(i).add(Integer.valueOf(split[j]));//存入当前标号i对应的前置依赖项
            }
        }

        //广度优先遍历
        Queue<Integer> queue = new LinkedList<>();
        Set<Integer> visited = new HashSet<>();
        Set<Integer> result = new HashSet<>();//用来记录结果并判断前置依赖项中是否有自己的特殊判断
        queue.offer(m);//从编号m开始
        visited.add(m);//将已经遍历的点放入集合中

        while (!queue.isEmpty()) {
            int u = queue.poll();//出队
            visited.add(u);  // 加入集合,用于后续判断是否循环依赖
            for (int v : map.get(u)) {
                if (visited.contains(v) && map.get(v).contains(u)) {
                    //意思就是你是通过u遍历到v,此时如果v能找到u那说明循环依赖
                    System.out.println(-1);
                    return;
                }
                if (result.contains(v)) {
                    continue;
                }
                queue.offer(v);
                result.add(v);
            }
        }
        //在一个大环中是否包含自己,也就是自己是否依赖自己,这样也是循环依赖,特殊情况
        if (result.contains(m)) {
            System.out.println(-1);
            return;
        }
        Integer[] start = result.toArray(new Integer[result.size()]);
        if (start.length == 1) {
            System.out.println(start[0]);
            return;
        }
        for (int i = 0; i < start.length - 1; ++i) {
            System.out.print(start[i] + ",");
        }
        System.out.println(start[start.length - 1]);
    }
}

python代码:


# If you need to import additional packages or classes, please import here.
from collections import defaultdict
from functools import cmp_to_key
from collections import deque
def func():
    # please define the python3 input here. For example: a,b = map(int, input().strip().split())
    # please finish the function body here.
    # please define the python3 output here. For example: print().
    n=int(input())#服务数
    m=int(input())#指定启动的服务编号
    g=[[] for _ in range(n)]
    rg=[[] for _ in range(n)]
    degrees=[0]*n
    for i in range(n):
        line=list(map(int, input().split(',')))
        for node in line[1:]:
            g[node].append(i)
            rg[i].append(node)
            degrees[i]+=1
    queue=deque()
    for i, d in enumerate(degrees):
        if d==0:
            if i==m:
                print("null")
                exit()
            queue.append(i)
    flag=False
    while queue:
        node=queue.pop()
        for nx_node in g[node]:
            degrees[nx_node]-=1
            if degrees[nx_node]==0:
                queue.append(nx_node)
                if nx_node==m:
                    flag=True
                    break
    if not flag:
        print('-1')
        exit()
    queue=deque([m])
    visited=[False]*n
    visited[m]=True
    ans=[]
    while queue:
        node =queue.pop()
        for nx_node in rg[node]:
            if not visited[nx_node]:
                visited[nx_node]=True
                queue.append(nx_node)
                ans.append(nx_node)
    ans.sort()
    print(",".join(str(i) for i in ans))
if __name__ == "__main__":
    func()

有问题留言,转载注明出处,谢谢!

你可能感兴趣的:(华为,算法,面试,java,python)