一.问题描述
Given an array of integers arr
, replace each element with its rank.
The rank represents how large the element is. The rank has the following rules:
- Rank is an integer starting from 1.
- The larger the element, the larger the rank. If two elements are equal, their rank must be the same.
- Rank should be as small as possible.
Example 1:
Input: arr = [40,10,20,30]
Output: [4,1,2,3]
Explanation: 40 is the largest element. 10 is the smallest. 20 is the second smallest. 30 is the third smallest.
Example 2:
Input: arr = [100,100,100]
Output: [1,1,1]
Explanation: Same elements share the same rank.
Example 3:
Input: arr = [37,12,28,9,100,56,80,5,12]
Output: [5,3,4,2,8,6,7,1,3]
Constraints:
0 <= arr.length <= 105
-109 <= arr[i] <= 109
二.解题思路
主要用hash。
将arr排序,然后hash每个值对应的rank,
然后一次遍历原arr,通过rank映射得到rank值。
虽然简单,但是实现起来可以看出代码功底。
时间复杂度:O(NlogN) (主要是排序的复杂度)
更多leetcode算法题解法: 专栏 leetcode算法从零到结束 或者 leetcode 解题目录 Python3 一步一步持续更新~
三.源码
#version 1
class Solution:
def arrayRankTransform(self, arr: List[int]) -> List[int]:
arr_s=sorted(list(set(arr)))
rank={arr_s[i]:i+1 for i in range(len(arr_s))}
return map(rank.get,arr)
#version 2
class Solution:
def arrayRankTransform(self, arr: List[int]) -> List[int]:
n=len(arr)
if n==0:return []
if n==1:return [1]
rst=[]
arr_s=sorted(arr)
order_idx,t={},1
for i in range(n):
if arr_s[i] not in order_idx:
order_idx[arr_s[i]]=t
t+=1
return [order_idx[arr[i]] for i in range(n)]