恢复排序后的数组

目录

  • 1. 问题背景
  • 2. 解决方案

1. 问题背景

给定一个乱序数组:

[7, 8, 1, 5, 3, 4, 2, 0, 9, 6]

将其从小到大排序后可以得到:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

从乱序到有序只需要调用一下 sort 函数,但要从有序恢复至原先的乱序又该如何做呢?

2. 解决方案

我们可以在排序的时候记录下索引的变化。起初:

Array: [7, 8, 1, 5, 3, 4, 2, 0, 9, 6]
Index: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

排序后:

Array: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Index: [7, 2, 6, 4, 5, 3, 9, 0, 1, 8]

根据 Index 的变化可以建立如下的映射:

7 → 0 2 → 1 6 → 2 4 → 3 5 → 4 3 → 5 9 → 6 0 → 7 1 → 8 8 → 9 7\to 0 \\ 2\to 1 \\ 6\to 2 \\ 4\to 3 \\ 5\to 4 \\ 3\to 5 \\ 9\to 6 \\ 0\to 7 \\ 1\to 8 \\ 8\to 9 \\ 70216243543596071889

排序的过程可以认为是把箭头左边对应位置上的数字移动到箭头右边对应的位置上,例如 6 → 2 6\to2 62 代表把第6个位置上的数字移动到第2个位置上。若要恢复原先的乱序,就要把第2个位置上的数字移动到第6个位置上。假设恢复前的数组为 _res,恢复后的数组为 res,那么不难看出有 res[6] = _res[2]

如何获得上面的映射呢?首先我们可以获得排序后的 Index 数组,然后根据这个数组建立一个逆映射:

import randomrandom.seed(0)
a = list(range(10))
random.shuffle(a)
print("Array:", a)
# Array: [7, 8, 1, 5, 3, 4, 2, 0, 9, 6]b = sorted(enumerate(a), key=lambda x: x[1])
idx_map, sorted_a = zip(*b)
print(idx_map)
# (7, 2, 6, 4, 5, 3, 9, 0, 1, 8)inverse_idx_map = {j: i for i, j in enumerate(idx_map)}

恢复原先的乱序数组只需要新开一个数组,然后遍历这个逆映射即可:

c = [None] * 10
for k, v in inverse_idx_map.items():c[k] = sorted_a[v]
print(c)
# [7, 8, 1, 5, 3, 4, 2, 0, 9, 6]

有一个问题是,空间复杂度一定是 O ( n ) O(n) O(n) 吗?可不可以降到 O ( 1 ) O(1) O(1)?答案是不可以。假设在某一步执行了 _res[k] = _res[v],那么位于 k 处的元素就会被彻底覆盖掉,无法再恢复。

据此可以总结整个算法流程:

  • 首先算出排序后的索引到排序前的索引映射 inverse_idx_map
  • 遍历这个映射,执行 res[k] = _res[v],其中 _res 是恢复前的数组,res 是恢复后的数组。

模版:

def get_inverse_idx_map(arr, sort_func):idx_map, sorted_arr = zip(*sorted(enumerate(arr), key=sort_func))inverse_idx_map = {j: i for i, j in enumerate(idx_map)}return inverse_idx_map, sorted_arrdef restore_arr(inverse_idx_map, sorted_arr):restored_arr = [None] * len(sorted_arr)for k, v in inverse_idx_map.items():restored_arr[k] = sorted_arr[v]return restored_arr

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/226076.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8S(二)—介绍

K8S的整体结构图 k8s对象 在 Kubernetes 系统中,Kubernetes 对象是持久化的实体。 Kubernetes 使用这些实体去表示整个集群的状态。 具体而言,它们描述了如下信息: 哪些容器化应用正在运行(以及在哪些节点上运行)可…

Pyqt5 适配windows缩放

写好的程序遇到 windows 不同文本百分比时,控件与窗口大小会出现 大小拥挤各种问题 解决方式 1、在创建窗口时,选择像素创建 2、做好控件像素大小设置 QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps) app QApplication(sys…

微服务实战系列之ZooKeeper(中)

前言 昨日博主的第一篇ZooKeeper,对它自身具备的能力做了初步介绍。书接上文,马不停蹄,我们继续挖掘它内在的美,充分把握它的核心与脉络。 揭秘ZooKeeper Q:集群一致性协同是如何进行的 我们讲到分布式,…

Renyi散度:Renyi divergence

有关Renyi散度的基本介绍挺多博客已经写了。本文章主要介绍最基础的概念,以及近些年论文中为啥老喜欢引用这个概念。 一.基础概念 Renyi散度主要是描述两个分布之间的关系。对一个离散的概率分布X,其定义域记作,其实就是概率不为零的点的集…

React脚手架搭建

React脚手架 脚手架:可以快速构建项目的基本架构。 脚手架安装命令 可全局安装脚手架 创建项目 来到当前目录下 create-react-app 项目名(不要大写字母) 运行项目 进到项目里,在项目目录下,执行 npm start &#xff…

Harmonyos系统列表组件和video组件的使用

列表组件和video组件 List组件和Grid组件的使用简介List组件的使用List组件简介使用ForEach渲染列表设置列表项分割线List列表滚动事件监听设置List排列方向 Grid组件的使用Grid组件简介使用ForEach渲染网格布局 video组件使用Video组件的接口表达形式为 List组件和Grid组件的使…

Python3 字符串 ----20231216

Python3 字符串 字符串是 Python 中最常用的数据类型。我们可以使用引号( 或 " )来创建字符串。 创建字符串很简单,只要为变量分配一个值即可。例如: var1 = Hello World! var2 = "Runoob"Python 访问字符串中的值 Python 不支持单字符类型,单字符在 Pyth…

C语言-Makefile

Makefile 什么是make? make 是个命令,是个可执行程序,用来解析 Makefile 文件的命令这个命令存放在 /usr/bin/ 什么是 makefile? makefile 是个文件,这个文件中描述了我们程序的编译规则咱们执行 make 命令的时候, m…

华为数通——路由冗余和备份

注:当一条路由的出接口down时,该路由会自动失效。 要求:数据优先走千兆链路。 R1 [ ]ip route-static 172.16.1.0 24 12.1.1.2 目的地址 掩码 下一条 [ ]ip route-static 172.16.1.0 24 21.1.1.2 preference 50 目的地址 …

OxLint 发布了,Eslint 何去何从?

由于最近的rust在前端领域的崛起,基于rust的前端生态链遭到rust底层重构,最近又爆出OxLint,是一款基于Rust的linter工具Oxlint在国外前端圈引起热烈讨论,很多大佬给出了高度评价;你或许不知道OxLint,相比ES…

MySQL 8.x temp空间不足问题

目录 一、系统环境 二、问题报错 三、问题回顾 四、解决问题 一、系统环境 系统Ubuntu20.04 数据库版本MySQL 8.0.21 二、问题报错 在MySQL上执行一个大的SQL查询报错Error writing file /tmp/MYfd142 (OS errno 28 - No space left on device) Exception in thread …

【深度学习】强化学习(六)基于值函数的学习方法

文章目录 一、强化学习问题1、交互的对象2、强化学习的基本要素3、策略(Policy)4、马尔可夫决策过程5、强化学习的目标函数6、值函数7、深度强化学习 二、基于值函数的学习方法 一、强化学习问题 强化学习的基本任务是通过智能体与环境的交互学习一个策略…

el-date-picker 选择一个或多个日期

el-date-picker可选择多个日期 type“dates” 加个s即可 <div><span>el-date-picker选择多个日期</span><el-date-pickertype"dates"v-model"dateList"placeholder"选择一个或多个日期"></el-date-picker></di…

js-正则表达式

一、基本规则 1.字面量表示法&#xff1a;正则表达式可以使用字面量形式创建&#xff0c;例如 /pattern/&#xff0c;其中 pattern 是要匹配的模式。 //直接匹配xxx字符 var reg /abc/ 2.构造函数表示法&#xff1a;你也可以使用 RegExp 构造函数来创建一个正则表达式&…

php链接oracle乱码,尝试把一个php的项目转成java,

​ 最近有个新需求&#xff0c;OA上的考勤信息确认&#xff0c;开始的时候搞了个php的版本&#xff0c;莫名其妙的数据库会乱码&#xff08;oracle&#xff09;(等有时间再写一篇php链接oracle数据库&#xff09;折腾了将近一个周&#xff0c;乱码莫名其妙的出现&#xff0c;代…

MyBatis环境的搭建

1.创建 Maven 工程 打开idea新建一个项目File → Project Structure → Project&#xff0c;build system中选择maven &#xff08;1&#xff09;由于 IDEA 中集成了 Maven&#xff0c;所以我们就不需要下载了&#xff0c;直接使用 IDEA 默认的 Maven 进行项目构建。 &#…

【NSX-T】10. 搭建NSX-T环境 —— 使用 BGP 配置 Tier-0 网关

目录 10.1 创建上行链路网段10.2 创建 Tier-0 网关&#xff08;1&#xff09;设置 Interface 信息&#xff08;2&#xff09;设置 BGP添加 BGP 邻居 &#xff08;3&#xff09;设置 BGP 路由重分发设置路由重新分发 10.3 连接 Tier-0 和 Tier-1 网关10.4 使用网络拓扑验证 Tier…

VLAN间的通讯---三层交换

一.三层交换 1.概念 使用三层交换技术实现VLAN间通信 三层交换二层交换 三层转发 2.基于CEF的MLS CEF是一种基于拓补转发的模型 转发信息库&#xff08;FIB&#xff09;临接关系表 转发信息库&#xff08;FIB&#xff09;可以理解为路由表 邻接关系表可以理解为MAC地址表…

Facebook广告系统结构

Facebook广告系统是一个复杂的大型系统&#xff0c;由多个组件和子系统相互配合工作&#xff0c;实现了广告的投放、拍卖、个性化推荐和效果评估等功能。下面小编讲讲Facebook广告系统的结构。 1、广告管理界面 广告管理界面是广告主与Facebook进行交互的入口&#xff0c;广告…

猿人学19题(原比赛平台)

这道题给我搞得有点懵了&#xff0c;我现在还没发现他到底要考察什么&#xff0c;这边我直接协商我的sessionid请求是直接就成功的。&#x1f602; 依旧是分析请求方式&#xff0c;抓包到返回数据的位置 现在可以知道这些数据是ajax返回的&#xff0c;请求的参数是page&#x…