• LeetCode 1743. 相邻元素对还原数组 哈希


    地址 https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/

    存在一个由 n 个不同元素组成的整数数组 nums ,但你已经记不清具体内容。好在你还记得 nums 中的每一对相邻元素。
    
    给你一个二维整数数组 adjacentPairs ,大小为 n - 1 ,其中每个 adjacentPairs[i] = [ui, vi] 表示元素 ui 和 vi 在 nums 中相邻。
    
    题目数据保证所有由元素 nums[i] 和 nums[i+1] 组成的相邻元素对都存在于 adjacentPairs 中,存在形式可能是 [nums[i], nums[i+1]] ,
    也可能是 [nums[i+1], nums[i]] 。这些相邻元素对可以 按任意顺序 出现。
    
    返回 原始数组 nums 。如果存在多种解答,返回 其中任意一个 即可。
    
     
    
    示例 1:
    
    输入:adjacentPairs = [[2,1],[3,4],[3,2]]
    输出:[1,2,3,4]
    解释:数组的所有相邻元素对都在 adjacentPairs 中。
    特别要注意的是,adjacentPairs[i] 只表示两个元素相邻,并不保证其 左-右 顺序。
    示例 2:
    
    输入:adjacentPairs = [[4,-2],[1,4],[-3,1]]
    输出:[-2,4,1,-3]
    解释:数组中可能存在负数。
    另一种解答是 [-3,1,4,-2] ,也会被视作正确答案。
    示例 3:
    
    输入:adjacentPairs = [[100000,-100000]]
    输出:[100000,-100000]
     
    
    提示:
    
    nums.length == n
    adjacentPairs.length == n - 1
    adjacentPairs[i].length == 2
    2 <= n <= 105
    -105 <= nums[i], ui, vi <= 105
    题目数据保证存在一些以 adjacentPairs 作为元素对的数组 nums

    算法1

    题目大意是记录了两个数的领接关系,需要我们拼凑出一个可能的链表形式。
    那么首先记录邻接的关系使用哈希表会加快查找速度,使用DFS进行各种尝试.
    这是比赛时的做法

    我们有了两者邻接的记录 那么尝试构造邻接的链表即可
    使用哈希记录两者邻接记录可以加速查找过程。
    deque或者链表方便头尾插入,可以更好的构造链表

     

    class Solution {
    public:
        unordered_map<int, vector<int>> vv;
        deque<int> dq;
    
        void dfs(int a, int b) {
            int aflag = 0; int bflag = 0;
            int aleft = vv[a][0];
            if (aleft == dq[1] && vv[a].size() > 1) {
                aleft = vv[a][1];
            }
    
            if (aleft != dq[1]) {
                dq.push_front(aleft);
                aflag = 1;
            }
    
    
            int bright = vv[b][0]; int backIdx = dq.size() - 1;
            if (bright == dq[backIdx - 1] && vv[b].size() > 1) {
                bright = vv[b][1];
            }
            if (bright != dq[backIdx - 1]) {
                bflag = 1;
                dq.push_back(bright);
            }
            if (aflag == 0 && bflag == 0) return;
            if (aflag == 0) aleft = a;
            if (bflag == 0) bright = b;
                dfs(aleft, bright);
        }
    
        vector<int> restoreArray(vector<vector<int>>& adjacentPairs) {
            for (int i = 0; i < adjacentPairs.size(); i++) {
                int a = adjacentPairs[i][0];
                int b = adjacentPairs[i][1];
                vv[a].push_back(b);
                vv[b].push_back(a);
            }
    
            int a = adjacentPairs[0][0]; int b = adjacentPairs[0][1];
    
            dq.push_front(a); dq.push_back(b);
            dfs(a, b);
    
            vector<int> ans(dq.begin(), dq.end());
            return ans;
        }
    };
    
     

    算法2 

    观察到链表的头尾只有一个连接节点 所以找到头 然后根据其相邻节点一路找下来就能恢复链表了

    class Solution {
    public:
        map<int, vector<int>> mm;
        vector<int> restoreArray(vector<vector<int>>& adjacentPairs) {
            for (int i = 0; i < adjacentPairs.size(); i++) {
                int a = adjacentPairs[i][0]; int b = adjacentPairs[i][1];
                mm[a].push_back(b); mm[b].push_back(a);
            }
            vector<int> ans; int head = 0;
            for (auto e : mm) {
                if (e.second.size() == 1) {
                    head = e.first;break;
                }
            }
            int prev = head; int curr = head;  int next = 0;
            while (1) {
                ans.push_back(curr);
                next = mm[curr][0];
                if (mm[curr].size() == 1 && next == prev) {
                    //找到了结尾 
                    break;
                }
                else {
                    if (next == prev) {
                        next = mm[curr][1];
                    }
                    prev = curr; curr = next;
                }
            }
            return ans;
        }
    };
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    vector详解
    笔记
    积木大赛
    codevs 1086 栈(Catalan数)
    不要把球传我
    同余方程 (codevs1200)
    最小集合
    数的计算
    产生数
    逃跑的拉尔夫
  • 原文地址:https://www.cnblogs.com/itdef/p/14361091.html
Copyright © 2020-2023  润新知