面试算法115:重建序列

题目

长度为n的数组org是数字1~n的一个排列,seqs是若干序列,请判断数组org是否为可以由seqs重建的唯一序列。重建的序列是指seqs所有序列的最短公共超序列,即seqs中的任意序列都是该序列的子序列。
例如,如果数组org为[4,1,5,2,6,3],而seqs为[[5,2,6,3],[4,1,5,2]],因为用[[5,2,6,3],[4,1,5,2]]可以重建出唯一的序列[4,1,5,2,6,3],所以返回true。如果数组org为[1,2,3],而seqs为[[1,2],[1,3]],因为用[[1,2],[1,3]]可以重建出两个序列,[1,2,3]或[1,3,2],所以返回false。

分析

超序列和子序列是两个相对的概念。如果序列A中的所有元素按照先后顺序都在序列B中出现,那么序列A是序列B的子序列,序列B是序列A的超序列。
在这里插入图片描述
如果得到的是有向图的拓扑排序序列,那么任意一条边的起始节点在拓扑排序序列中一定位于终止节点的前面。因此,由seqs重建的序列就是由seqs构建的有向图的拓扑排序的序列。这个问题就转变成判断一个有向图的拓扑排序序列是否唯一。

public class Test {
   
    public static void main(String[] args) {
   
        int[] org = {
   4, 1, 5, 2, 6, 3};
        List<Integer> list1 = Arrays.asList(5, 2, 6, 3);
        List<Integer> list2 = Arrays.asList(4, 1, 5, 2);
        List<List<Integer>> seqs = Arrays.asList(list1, list2);
        boolean result = sequenceReconstruction(org, seqs);
        System.out.println(result);
    }

    public static boolean sequenceReconstruction(int[] org, List<List<Integer>> seqs) {
   
        Map<Integer, Set<Integer>> graph = new HashMap<>();
        Map<Integer, Integer> inDegrees = new HashMap<>();
        for (List<Integer> seg : seqs) {
   
            for (int num : seg) {
   
                if (num < 1 || num > org.length) {
   
                    return false;
                }

                graph.putIfAbsent(num, new HashSet<>());
                inDegrees.putIfAbsent(num, 0);
            }
            for (int i = 0; i < seg.size() - 1; i++) {
   
                int num1 = seg.get(i);
                int num2 = seg.get(i + 1);
                if (!graph.get(num1).contains(num2)) {
   
                    graph.get(num1).add(num2);
                    inDegrees.put(num2, inDegrees.get(num2) + 1);
                }
            }
        }

        Queue<Integer> queue = new LinkedList<>();
        for (int num : inDegrees.keySet()) {
   
            if (inDegrees.get(num) == 0) {
   
                queue.add(num);
            }
        }

        Queue<Integer> built = new LinkedList<>();
        while (queue.size() == 1) {
   
            int num = queue.remove();
            built.add(num);
            for (int next : graph.get(num)) {
   
                inDegrees.put(next, inDegrees.get(next) - 1);
                if (inDegrees.get(next) == 0) {
   
                    queue.add(next);
                }
            }
        }

        int[] result = new int[built.size()];
        result = built.stream().mapToInt(i -> i).toArray();
        return Arrays.equals(result, org);
    }

}

相关推荐

  1. 面试算法-135-最长递增子序列的个数

    2024-01-12 14:12:02       34 阅读
  2. 面试算法-115-组合总和

    2024-01-12 14:12:02       36 阅读
  3. 面试算法-113-打家劫舍

    2024-01-12 14:12:02       39 阅读
  4. 面试算法-114-打家劫舍 II

    2024-01-12 14:12:02       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-12 14:12:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-12 14:12:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-12 14:12:02       82 阅读
  4. Python语言-面向对象

    2024-01-12 14:12:02       91 阅读

热门阅读

  1. 数据结构---栈和队列

    2024-01-12 14:12:02       60 阅读
  2. 计算机图形学作业:三阶贝塞尔曲面

    2024-01-12 14:12:02       58 阅读
  3. 第九讲_css渐变

    2024-01-12 14:12:02       56 阅读
  4. diffusers flask streamlit 简洁可视化文生图页面

    2024-01-12 14:12:02       55 阅读
  5. 读书分享-《认知觉醒》揭示心智潜能的启迪之作

    2024-01-12 14:12:02       61 阅读