我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python 根据相邻关系还原数组的两种方式(单向构造和双向构造)

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python 根据相邻关系还原数组的两种方式(单向构造和双向构造)

目录
  • 题目描述
    • 示例 2:
    • 示例 3:
  • 单向构造(哈希表计数)
    • 双向构造(双指针)
      • 最后

        题目描述

        这是 LeetCode 上的 1743. 从相邻元素对还原数组 ,难度为 中等。

        Tag : 「哈希表」、「双指针」、「模拟」

        存在一个由 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 <= 10510^5105
        • -10510^5105 <= nums[i], ui, vi <= 10510^5105
        • 题目数据保证存在一些以 adjacentPairs 作为元素对的数组

        单向构造(哈希表计数)

        根据题意,由于所有的相邻关系都会出现在 numsnumsnums 中,假设其中一个合法数组为 ansansans,长度为 nnn。

        那么显然 ans[0]ans[0]ans[0] 和 ans[n−1]ans[n - 1]ans[n−1] 在 numsnumsnums 中只存在一对相邻关系,而其他 ans[i]ans[i]ans[i] 则存在两对相邻关系。

        因此我们可以使用「哈希表」对 numsnumsnums 中出现的数值进行计数,找到“出现一次”的数值作为 ansansans 数值的首位,然后根据给定的相邻关系进行「单向构造」,为了方便找到某个数其相邻的数是哪些,我们还需要再开一个「哈希表」记录相邻关系。

        Java 代码:

        
        class Solution {
            public int[] restoreArray(int[][] aps) {
                int m = aps.length, n = m + 1;
                Map<Integer, Integer> cnts = new HashMap<>();
                Map<Integer, List<Integer>> map = new HashMap<>();
                for (int[] ap : aps) {
                    int a = ap[0], b = ap[1];
                    cnts.put(a, cnts.getOrDefault(a, 0) + 1);
                    cnts.put(b, cnts.getOrDefault(b, 0) + 1);
                    List<Integer> alist = map.getOrDefault(a, new ArrayList<>());
                    alist.add(b);
                    map.put(a, alist);
                    List<Integer> blist = map.getOrDefault(b, new ArrayList<>());
                    blist.add(a);
                    map.put(b, blist);
                }
                int start = -1;
                for (int i : cnts.keySet()) {
                    if (cnts.get(i) == 1) {
                        start = i;
                        break;
                    }
                }
                int[] ans = new int[n];
                ans[0] = start;
                ans[1] = map.get(start).get(0);
                for (int i = 2; i < n; i++) {
                    int x = ans[i - 1];
                    List<Integer> list = map.get(x);
                    for (int j : list) {
                        if (j != ans[i - 2]) ans[i] = j;
                    }
                }
                return ans;
            }
        }
        

        Python 3 代码:

        
        class Solution:
            def restoreArray(self, adjacentPairs: List[List[int]]) -> List[int]:
                m = n = len(adjacentPairs)
                n += 1
                cnts = defaultdict(int)
                hashmap = defaultdict(list)
                for a, b in adjacentPairs:
                    cnts[a] += 1
                    cnts[b] += 1
                    hashmap[a].append(b)
                    hashmap[b].append(a)
                start = -1
                for i, v in cnts.items():
                    if v == 1:
                        start = i
                        break
                ans = [0] * n
                ans[0] = start
                ans[1] = hashmap[start][0]
                for i in range(2, n):
                    x = ans[i - 1]
                    for j in hashmap[x]:
                        if j != ans[i - 2]:
                            ans[i] = j
                return ans
        
        • 时间复杂度:O(n)O(n)O(n)
        • 空间复杂度:O(n)O(n)O(n)

        双向构造(双指针)

        在解法一中,我们通过「哈希表」计数得到 ansansans 首位的原始作为起点,进行「单向构造」。
        那么是否存在使用任意数值作为起点进行的双向构造呢?
        答案是显然的,我们可以利用 ansansans 的长度为 2<=n<=1052 <= n <= 10^52<=n<=105,构造一个长度 10610^6106 的数组 qqq(这里可以使用 static 进行加速,让多个测试用例共享一个大数组)。

        这里 qqq 数组不一定要开成 1e61e61e6 大小,只要我们 qqq 大小大于 ansansans 的两倍,就不会存在越界问题。

        从 qqq 数组的 中间位置 开始,先随便将其中一个元素添加到中间位置,使用「双指针」分别往「两边拓展」(l 和 r 分别指向左右待插入的位置)。

        当 l 指针和 r 指针直接已经有 nnn 个数值,说明整个 ansansans 构造完成,我们将 [l+1,r−1][l + 1, r - 1][l+1,r−1] 范围内的数值输出作为答案即可。

        Java 代码:

        
        class Solution {
            static int N = (int)1e6+10;
            static int[] q = new int[N];
            public int[] restoreArray(int[][] aps) {
                int m = aps.length, n = m + 1;
                Map<Integer, List<Integer>> map = new HashMap<>();
                for (int[] ap : aps) {
                    int a = ap[0], b = ap[1];
                    List<Integer> alist =  map.getOrDefault(a, new ArrayList<>());
                    alist.add(b);
                    map.put(a, alist);
                    List<Integer> blist = map.getOrDefault(b, new ArrayList<>());
                    blist.add(a);
                    map.put(b, blist);
                }
                int l = N / 2, r = l + 1;
                int std = aps[0][0];
                List<Integer> list = map.get(std);
                q[l--] = std;
                q[r++] = list.get(0);
                if (list.size() > 1) q[l--] = list.get(1);
                while ((r - 1) - (l + 1) + 1 < n) {
                    List<Integer> alist = map.get(q[l + 1]);
                    int j = l;
                    for (int i : alist) {
                        if (i != q[l + 2]) q[j--] = i;
                    }
                    l = j;
        
                    List<Integer> blist = map.get(q[r - 1]);
                    j = r;
                    for (int i : blist) {
                        if (i != q[r - 2]) q[j++] = i;
                    }
                    r = j;
                }
                int[] ans = new int[n];
                for (int i = l + 1, idx = 0; idx < n; i++, idx++) {
                    ans[idx] = q[i];
                }
                return ans;
            }
        }
        
        

        Python 3 代码:

        
        class Solution:
            N = 10 ** 6 + 10
            q = [0] * N
        
            def restoreArray(self, adjacentPairs: List[List[int]]) -> List[int]:
                m = len(adjacentPairs)
                n = m + 1
                hashmap = defaultdict(list)
                for a, b in adjacentPairs:
                    hashmap[a].append(b)
                    hashmap[b].append(a)
                l = self.N // 2
                r = l + 1
                std = adjacentPairs[0][0]
                lt = hashmap[std]
                self.q[l] = std
                l -= 1
                self.q[r] = lt[0]
                r += 1
                if len(lt) > 1:
                    self.q[l] = lt[1]
                    l -= 1
                while (r-1)-(l+1)+1<n:
                    alt = hashmap[self.q[l+1]]
                    j = l
                    for i in alt:
                        if i != self.q[l+2]:
                            self.q[j] = i
                            j -= 1
                    l = j
                    
                    blt = hashmap[self.q[r-1]]
                    j = r
                    for i in blt:
                        if i != self.q[r - 2]:
                            self.q[j] = i
                            j += 1
                    r = j
                ans = [0] * n
                for idx in range(n):
                    ans[idx] = self.q[idx+l+1]
                return ans
        
        

        时间复杂度:O(n)O(n)O(n)
        空间复杂度:O(n)O(n)O(n)

        最后

        到此这篇关于Python 根据相邻关系还原数组的两种方式(单向构造和双向构造)的文章就介绍到这了,更多相关Python 相邻还原数组内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

        免责声明:

        ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

        ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

        Python 根据相邻关系还原数组的两种方式(单向构造和双向构造)

        下载Word文档到电脑,方便收藏和打印~

        下载Word文档

        猜你喜欢

        Python 根据相邻关系还原数组的两种方式(单向构造和双向构造)

        目录题目描述示例 2:示例 3:单向构造(哈希表计数)双向构造(双指针)最后题目描述这是 LeetCode 上的 1743. 从相邻元素对还原数组 ,难度为 中等。Tag : 「哈希表」、「双指针」、「模拟」存在一个由 n 个不同元素组成的
        2022-06-02

        编程热搜

        • Python 学习之路 - Python
          一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
          Python 学习之路 - Python
        • chatgpt的中文全称是什么
          chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
          chatgpt的中文全称是什么
        • C/C++中extern函数使用详解
        • C/C++可变参数的使用
          可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
          C/C++可变参数的使用
        • css样式文件该放在哪里
        • php中数组下标必须是连续的吗
        • Python 3 教程
          Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
          Python 3 教程
        • Python pip包管理
          一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
          Python pip包管理
        • ubuntu如何重新编译内核
        • 改善Java代码之慎用java动态编译

        目录