LintCode 题解丨Facebook面试题:序列重构

简介: LintCode 题解丨Facebook面试题:序列重构

判断是否序列 ​org​ 能唯一地由 ​seqs​重构得出. ​org​是一个由从1到n的正整数排列而成的序列,1≤n≤10​^4​​。 重构表示组合成​seqs​的一个最短的父序列 (意思是,一个最短的序列使得所有 ​seqs​里的序列都是它的子序列).

判断是否有且仅有一个能从 ​seqs​重构出来的序列,并且这个序列是​org​。

在线评测地址:LintCode 领扣

样例1:
输入:org = [1,2,3], seqs = [[1,2],[1,3]]
输出: false
解释:
[1,2,3] 并不是唯一可以被重构出的序列,还可以重构出 [1,3,2]
样例2:
输入: org = [1,2,3], seqs = [[1,2]]
输出: false
解释:
能重构出的序列只有 [1,2].
样例3:
输入: org = [1,2,3], seqs = [[1,2],[1,3],[2,3]]
输出: true
解释:
序列 [1,2], [1,3], 和 [2,3] 可以唯一重构出 [1,2,3].
样例4:
输入:org = [4,1,5,2,6,3], seqs = [[5,2,6,3],[4,1,5,2]]
输出:true
【题解】

九章算法班里讲过的拓扑排序,只要保证 queue 里最多同时只有一个元素即可。 所以这是 queue 用 list 然后每次 pop 也可以,反正只有一个数。

public class Solution {

/**
 * @param org: a permutation of the integers from 1 to n
 * @param seqs: a list of sequences
 * @return: true if it can be reconstructed only one or false
 */
public boolean sequenceReconstruction(int[] org, int[][] seqs) {
    Map<Integer, Set<Integer>> graph = buildGraph(seqs);
    List<Integer> topoOrder = getTopoOrder(graph);
    
    if (topoOrder == null || topoOrder.size() != org.length) {
        return false;
    }
    for (int i = 0; i < org.length; i++) {
        if (org[i] != topoOrder.get(i)) {
            return false;
        }
    }
    return true;
}

private Map<Integer, Set<Integer>> buildGraph(int[][] seqs) {
    Map<Integer, Set<Integer>> graph = new HashMap();
    for (int[] seq : seqs) {
        for (int i = 0; i < seq.length; i++) {
            if (!graph.containsKey(seq[i])) {
                graph.put(seq[i], new HashSet<Integer>());
            }
        }
    }
    for (int[] seq : seqs) {
        for (int i = 1; i < seq.length; i++) {
            graph.get(seq[i - 1]).add(seq[i]);
        }
    }
    return graph;
}

private Map<Integer, Integer> getIndegrees(Map<Integer, Set<Integer>> graph) {
    Map<Integer, Integer> indegrees = new HashMap();
    for (Integer node : graph.keySet()) {
        indegrees.put(node, 0);
    }
    for (Integer node : graph.keySet()) {
        for (Integer neighbor : graph.get(node)) {
            indegrees.put(neighbor, indegrees.get(neighbor) + 1);
        }
    }
    return indegrees;
}

private List<Integer> getTopoOrder(Map<Integer, Set<Integer>> graph) {
    Map<Integer, Integer> indegrees = getIndegrees(graph);
    Queue<Integer> queue = new LinkedList();
    List<Integer> topoOrder = new ArrayList();
    
    for (Integer node : graph.keySet()) {
        if (indegrees.get(node) == 0) {
            queue.offer(node);
            topoOrder.add(node);
        }
    }
    
    while (!queue.isEmpty()) {
        if (queue.size() > 1) {
            return null;
        }
        
        Integer node = queue.poll();
        for (Integer neighbor : graph.get(node)) {
            indegrees.put(neighbor, indegrees.get(neighbor) - 1);
            if (indegrees.get(neighbor) == 0) {
                queue.offer(neighbor);
                topoOrder.add(neighbor);
            }
        }
    }
    
    if (graph.size() == topoOrder.size()) {
        return topoOrder;
    }
    
    return null;
}

}
更多题解参考:

九章算法 - 帮助更多中国人找到好工作,硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧

相关文章
|
JSON 缓存 前端开发
基于Axios二次封装请求库,带你重构面试亮点(一)
基于Axios二次封装请求库,带你重构面试亮点
97 0
|
6月前
|
算法 测试技术 持续交付
Python面试:代码审查与重构相关问题
【4月更文挑战第19天】本文讨论了Python面试中常被问到的代码审查和重构主题。代码审查涉及理解审查目的、使用工具(如GitHub PR)和遵循PEP 8规范。要避免仅关注表面错误,忽视可读性,同时提供具体反馈。重构时,要理解其原则,熟悉各种手法,并借助单元测试和持续集成保证质量。遵循小步快跑原则,评估技术债务,记录重构步骤。文中通过示例展示了如何将原始代码重构为更清晰的抽象类结构,以提高代码组织性。掌握这些技能对于面试成功至关重要。
51 0
|
缓存 API
基于Axios二次封装请求库,带你重构面试亮点(二)
基于Axios二次封装请求库,带你重构面试亮点
64 0
|
机器学习/深度学习 人工智能 自动驾驶
强化学习从基础到进阶--案例与实践含面试必知必答[10]:模仿学习、行为克隆、逆强化学习、第三人称视角模仿学习、序列生成和聊天机器人
强化学习从基础到进阶--案例与实践含面试必知必答[10]:模仿学习、行为克隆、逆强化学习、第三人称视角模仿学习、序列生成和聊天机器人
强化学习从基础到进阶--案例与实践含面试必知必答[10]:模仿学习、行为克隆、逆强化学习、第三人称视角模仿学习、序列生成和聊天机器人
【牛客面试必刷TOP101】有效括号序列、滑动窗口的最大值
【牛客面试必刷TOP101】有效括号序列、滑动窗口的最大值
|
Web App开发 缓存 前端开发
Facebook 重构:抛弃 Sass / Less ,迎接原子化 CSS 时代
随着 Facebook 和 Twitter 最近的产品部署,我认为一个新的趋势正在缓慢增长:Atomic CSS-in-JS。
|
C++
剑指Offer - 面试题7:重构二叉树 (力扣 - 105、从前序与中序遍历序列构造二叉树)
剑指Offer - 面试题7:重构二叉树 (力扣 - 105、从前序与中序遍历序列构造二叉树)
61 0
|
机器学习/深度学习 人工智能 算法
强化学习从基础到进阶-常见问题和面试必知必答[1]:强化学习概述、序列决策、动作空间定义、策略价值函数、探索与利用、Gym强化学习实验
强化学习从基础到进阶-常见问题和面试必知必答[1]:强化学习概述、序列决策、动作空间定义、策略价值函数、探索与利用、Gym强化学习实验
Leecode 面试题57 - II. 和为s的连续正数序列
Leecode 面试题57 - II. 和为s的连续正数序列
46 0
|
JavaScript Go
剑指Offer面试题57 - II. 和为s的连续正数序列
剑指Offer面试题57 - II. 和为s的连续正数序列
剑指Offer面试题57 - II. 和为s的连续正数序列