互联网行业的小白,写博客的目的是为了记录自己的学习过程、对自己学习中所犯的错误做一个总结。由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!
题目描述
题目传送门:有多少小于当前数字的数字
给你一个数组 nums
,对于其中每个元素 nums[i]
,请你统计数组中比它小的所有数字的数目。
换而言之,对于每个 nums[i]
你必须计算出有效的j
的数量,其中 j
满足j != i
且nums[j] < nums[i]
。
以数组形式返回答案。
示例 1:
输入:nums = [8,1,2,2,3]
输出:[4,0,1,1,3]
解释:
对于 nums[0]=8 存在四个比它小的数字:(1,2,2 和 3)。
对于 nums[1]=1 不存在比它小的数字。
对于 nums[2]=2 存在一个比它小的数字:(1)。
对于 nums[3]=2 存在一个比它小的数字:(1)。
对于 nums[4]=3 存在三个比它小的数字:(1,2 和 2)。
示例 2:
输入:nums = [6,5,4,8]
输出:[2,1,0,3]
示例 3:
输入:nums = [7,7,7,7]
输出:[0,0,0,0]
提示:
2 <= nums.length <= 500
0 <= nums[i] <= 100
题解
暴力实现 |
最简单粗暴的方式:采用暴力实现,二重循环遍历数组即可,即两层for循环暴力查找,时间复杂度明显为 O ( n 2 ) O(n^2) O(n2)。
AC代码
class Solution:
def smallerNumbersThanCurrent(self, nums: List[int]) -> List[int]:
ans = []
for index1, value1 in enumerate(nums):
count = 0
for index2, value2 in enumerate(nums):
if index1 != index2 and value1 > value2:
count += 1
ans.append(count)
return ans
但是采用这种方式,因为涉及二重循环,其时间复杂度太高,不建议采取。
计数排序 |
这种方法只需要遍历一遍待排数组即可,具体思路如下:
提前建立一个从0-100的空数组用来计数,在待排数组里遇到一个数就在计数数组里对应位置+1。
题目要求比此数小的,也就是刚才的计数数组里,当前位置(表示对应的nums里的一个数n),之前的数(比n小的数字的个数)的总和。理解不了没关系,看一遍代码就懂了。
AC代码
class Solution:
def smallerNumbersThanCurrent(self, nums: List[int]) -> List[int]:
count = [0] * 101 # 计数数组:题目强调0 <= nums[i] <= 100,则最多101个空间即可
out = [] # 记录最终答案
for n in nums:
count[n] += 1 # 计数器,第n个数加1
sum = 0 # 存放count数组的累加值
ans = [] # 将比它小的数列举出进行存放
for value in count:
ans.append(sum)
sum += value
for value in nums:
out.append(ans[value])
return out
注意
- 计数排序可能是所有排序里最快的一种,因为它不涉及比较。
- 缺点:需要的空间很大。所以一般只涉及数字且范围较小的时候,还能应付,一旦涉及到字母混数字排序就无能为力了。
排序哈希 |
首先要找小于当前数字的数字,那么从小到大排序之后,该数字之前的数字就都是比它小的了。
所以可以定义一个新数组,将数组排个序。
排序之后,其实每一个数值的下标就代表这前面有几个比它小的了。
此时有一个情况,就是数值相同怎么办?
可以这样处理:将数组降序排列,此时要得到小于当前数字的数字
,它与降序排列的下标有什么关系呢?
要 找 的 小 于 当 前 数 字 的 数 字 = l e n ( n u m s ) − 1 − 数 组 下 标 要找的小于当前数字的数字=len(nums)-1-数组下标 要找的小于当前数字的数字=len(nums)−1−数组下标
此时再用一个哈希表hash来做数值和下标的映射,这样就可以通过数值快速知道下标。
AC代码
class Solution:
def smallerNumbersThanCurrent(self, nums: List[int]) -> List[int]:
out = []
temp = sorted(nums, reverse=True) # 降序排列
hash = [0] * 101 # 根据题意,哈希表最多101个空间即可
for i, j in enumerate(temp):
hash[j] = len(nums) - 1 - i # 此写法为了避免nums中有相同的数
for i in nums:
out.append(hash[i])
return out
码字不易,您的
支持
就是我坚持
下去的动力,一起加油哦。