LC 1331. 数组序号转换 (opens new window) (opens new window)
简单
# 问题描述
给你一个整数数组 arr
,请你将数组中的每个元素替换为它们排序后的序号。
序号代表了一个元素有多大。序号编号的规则如下:
- 序号从 1 开始编号。
- 一个元素越大,那么序号越大。如果两个元素相等,那么它们的序号相同。
- 每个数字的序号都应该尽可能地小。
示例 1:
输入:arr = [40,10,20,30]
输出:[4,1,2,3]
解释:40 是最大的元素。 10 是最小的元素。 20 是第二小的数字。 30 是第三小的数字。
示例 2:
输入:arr = [100,100,100]
输出:[1,1,1]
解释:所有元素有相同的序号。
示例 3:
输入:arr = [37,12,28,9,100,56,80,5,12]
输出:[5,3,4,2,8,6,7,1,3]
提示:
0 <= arr.length <= 105
-109 <= arr[i] <= 109
# 哈希表
复制一份原数组进行排序,然后用一个哈希表保存首个出现元素的序号,最后遍历一次原数组,从哈希表中找出对应元素的序号。
/**
* @param {number[]} arr
* @return {number[]}
*/
var arrayRankTransform = function (arr) {
const map = new Map()
const order = Array.from(arr).sort((a, b) => a - b)
for (let i = 0; i < order.length; i++) {
if (!map.has(order[i])) map.set(order[i], map.size + 1)
}
const ans = new Array()
for (let i = 0; i < arr.length; i++) {
ans[i] = map.get(arr[i])
}
return ans
}
- 时间复杂度:, 是输入数组的长度,排序消耗 时间。
- 空间复杂度:。有序数组和哈希表各消耗 空间。
# 二分查找
复制一份原数组去重并排序,然后遍历原数组,利用二分查找找出该元素在排序后数组中的位置。
/**
* @param {number[]} arr
* @return {number[]}
*/
var arrayRankTransform = function (arr) {
const order = Array.from(new Set(arr)).sort((a, b) => a - b)
const ans = new Array(arr.length)
for (let j = 0; j < arr.length; j++) {
let l = 0
let r = order.length - 1
while (l < r) {
const mid = (l + r) >> 1
if (order[mid] === arr[j]) {
l = mid
break
} else if (order[mid] < arr[j]) {
l = mid + 1
} else {
r = mid
}
}
ans[j] = l + 1
}
return ans
}
- 时间复杂度:, 是输入数组的长度,排序和二分查找消耗 时间,。
- 空间复杂度:。有序数组消耗 空间。
上次更新: 2023/01/31 19:48:05
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 , 转载请注明出处!