#414 Third Maximum Number
Given an integer array
nums
, return the third distinct maximum number in this array. If the third maximum does not exist, return the maximum number.
解题思路:
1.先找出数列中的最大值,然后删掉
2.重复第一步
3.再找出此时数列中的最大值,return
以上是数列中有第三个最大值存在的情况。如果数列中不存在的话,那么第一次找出的最大值就要提前保留起来,最后用于return。
判断是否存在的第三个最大值的方法是,看删掉最大值之后,第一个以及第二个(如果有的话),数列还是否有元素。
class Solution:
def thirdMax(self, nums: List[int]) -> int:
first, count = max(nums), 0
while len(nums) > 0 and count < 3:
num_of_interest = max(nums)
count += 1
if count < 3:
for i in range(nums.count(num_of_interest)):
nums.remove(num_of_interest)
if count == 3:
return num_of_interest
else:
return first
runtime:
看起来很慢。看还可以怎么优化步骤。
参考35ms的solution:
可以先用set()来删掉多余重复的数。
先求得最大值。
如果数列长度小于3,直接输出这个最大值。
否则删掉,再求,再删,再输出第三个最大值。
重写一遍:
class Solution:
def thirdMax(self, nums: List[int]) -> int:
nums = set(nums)
first = max(nums)
if len(nums) < 3:
return first
nums.remove(first)
second = max(nums)
nums.remove(second)
return max(nums)
runtime:
稍微好一点点。
去Forum还看到一个更好的思路,不需要担心超过3次的。
创建一个有三个元素,都为负无穷的数列。
然后for循环nums,最大的三个值占坑。
class Solution:
def thirdMax(self, nums: List[int]) -> int:
spots = [float('-inf'), float('-inf'), float('-inf')]
for i in nums:
if i not in spots:
if i > spots[0]: spots = [i, spots[0], spots[1]]
elif i > spots[1]: spots = [spots[0], i, spots[1]]
elif i > spots[2]: spots = [spots[0], spots[1], i]
return max(spots) if float('-inf') in spots else spots[2]
runtime:
稍微麻烦的是要重新arrange三个坑位。
#448 Find All Numbers Disappeared in an Array
Given an array
nums
ofn
integers wherenums[i]
is in the range[1, n]
, return an array of all the integers in the range[1, n]
that do not appear innums
.Follow up: Could you do it without extra space and in
O(n)
runtime? You may assume the returned list does not count as extra space.
解题思路:
如果不另外占用记忆空间,那么只能直接在nums上处理了。
1)for循环range(1, len(nums) + 1)
2)nums里有的删掉
3)没有的加上
最后剩下的就是原来缺的了。
有点麻烦的是,删掉的数字可能不只一个,所以要重复删。这里我就用了一个while循环。删到没有为止。
class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
for i in range(1, len(nums)+1):
if i not in nums:
nums.append(i)
else:
while i in nums:
nums.remove(i)
return nums
runtime:
但是却超时间了?按说这个不就是O(N)吗?不理解为啥会超时。
(后来查了一下time complexity的资料,原来是not in或者in,本身也是O(N),所以这里就变成了O(N^2),这就是为什么慢的原因了)
看一下别人的solution:
1)把nums里的每个数,减1之后作为idx,把nums[idx]加上符号。
2)然后筛选出nums里还是正值的idx,就是解。
(我去,tql
试写一下:
class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
for i in range(len(nums)):
index = abs(nums[i]) - 1
nums[index] = -abs(nums[index])
return [i + 1 for i in range(len(nums)) if nums[i] > 0]
runtime:
nice。
继续翻评论看到,标注负号,还可以用 *= -1的方法。if nums[index] >0的话。这样就避免了重复index的问题了。学习了。
还有一种one-liner的解法:
用range(1, len(nums) + 1)这个集合直接减去set(nums),得到的就是解。
试写一下:
class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
return set(range(1,len(nums)+1)) - set(nums)
runtime:
但是这种解法因为新创建了一个set(range(1, len(nums)+1)),所以space complexity上不合要求。