【vivo2021届秋季校招】1. 编译依赖问题 <拓扑排序、堆>

【vivo2021届秋季校招】1. 编译依赖问题

一个完整的软件项目往往会包含很多由代码和文档组成的源文件。编译器在编译整个项目的时候,可能需要按照依赖关系来依次编译每个源文件。
比如,A.cpp 依赖 B.cpp,那么在编译的时候,编译器需要先编译 B.cpp,才能再编译 A.cpp。

假设现有 0,1,2,3 四个文件,0号文件依赖1号文件,1号文件依赖2号文件,3号文件依赖1号文件,则源文件的编译顺序为 2,1,0,3 或 2,1,3,0。

现给出文件依赖关系,如 1,2,-1,1,表示0号文件依赖1号文件,1号文件依赖2号文件,2号文件没有依赖,3号文件依赖1号文件。请补充完整程序,返回正确的编译顺序。注意如有同时可以编译多个文件的情况,按数字升序返回一种情况即可,比如前述案例输出为:2,1,0,3

示例输入:

"1,2,-1,1"

输出例子:

"2,1,0,3"

题解

拓扑排序,使用优先队列(小根堆)处理:同时可以编译多个文件的情况,按数字升序返回。

import java.util.*;

public class Solution {
    public String compileSeq(String input) {
        String[] fileNum = input.split(",");
        int n = fileNum.length;
        int[] fileIds = new int[n];

        // 小根堆 下标
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        // 从没有依赖的文件开始,为-1说明该文件id不用前置文件,将id加入堆中
        for (int i = 0; i < n; i++) {
            fileIds[i] = Integer.parseInt(fileNum[i]);
            if (fileIds[i] == -1) {
                pq.offer(i);
            }
        }
        //收集结果
        StringBuilder sb = new StringBuilder();

        // 利用小根堆实现拓扑排序
        while (!pq.isEmpty()) {
            // 可以先执行的前置文件
            int fileId = pq.poll();
            sb.append(fileId).append(",");
            // 将所有依赖 fileId 的文件加入小根堆
            for (int i = 0; i < n; i++) {
                if (fileIds[i] == fileId) {
                    pq.offer(i);
                }
            }
        }

        //删除最后一个,
        return sb.deleteCharAt(sb.length() - 1).toString();
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        String s = solution.compileSeq("1,2,-1,1");
        System.out.println(s);
    }
}

你可能感兴趣的:(力扣及OJ,#,树,图结构,java)