招银网络科技2019笔试的代码填空题
题目描述
给定N个数字,范围都在1-N
之间,输出每个数字出现的次数。
要求:时间复杂度O(N)
,空间复杂度O(1)
.
思路
空间复杂度是O(1)
的情况就是要将每个数字出现的次数保存在原数组中。考虑到数字的范围是1-N
,如果每个数字都不重复,则数组中第i
个位置应该正好是i
,即第一个数是1
,第二个数是2
,依次类推。
根据以上思路,可以对第i
个进行以下判断:
- 先令
tmp=nums[i]-1
,则nums[tmp]
记录的是第i
个数原本应该对应的位置。 - 如果
nums[i]<0
,则说明当前位置上存的是计数count,而不是数字,则可以继续; - 如果
nums[tmp] > 0
,则说明第i
个位置被其他数字占用了,则将该数字换到nums[i]
的位置上,nums[tmp]=-1
表示这个位置对应的数出现了一次。 - 如果
nums[tmp]<=0
,则说明第i
个位置的数已经出现了不止一次,则将次数-1
,且nums[i]
置0(认为这个位置的数还没出现过)。
code
class Solution(object):
def findDuplicates(self, nums):
i = 0
while i < len(nums):
tmp = nums[i] - 1
if nums[i] < 0:
i += 1
elif nums[tmp] > 0:
nums[i] = nums[tmp]
nums[tmp] = -1
else:
nums[i] = 0
nums[tmp] -= 1
# print('after ', i,nums[i], tmp, nums[tmp], nums)
res = []
for index, x in enumerate(nums):
if x < -1:
res.append(index + 1)
return res