不见五陵豪杰墓,无花无酒锄作田。《唐伯虎点秋香》
计算右侧小于当前元素的个数leetcode-cn.com
给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
示例:
#输入: [5,2,6,1]
#输出: [2,1,1,0]
#解释:
5 的右侧有 2 个更小的元素 (2 和 1).
2 的右侧仅有 1 个更小的元素 (1).
6 的右侧有 1 个更小的元素 (1).
1 的右侧有 0 个更小的元素.
暴力的解法是对每个元素进行元素右侧的遍历,时间复杂度为O(n2);看着有些类似冒泡排序一样,不过这种解法力扣判定是超时的。所以只能想办法降低时间复杂度,首先是库函数,之前也有过类似的题。使用bisect库函数进行二分查找元素的下标进行记录,并将新元素进行对应位置的插入,使得整个列表是有序的。
class Solution:
def countSmaller(self, nums: List[int]) -> List[int]:
sortns = []
res = []
for n in reversed(nums):
idx = bisect.bisect_left(sortns, n)
res.append(idx)
sortns.insert(idx,n)
return res[::-1]
因为是求比右侧的大的元素,因此可以从元素的右边开始遍历,这样就不用每次遍历一次元素右边所有的元素;并且最后要记得将顺序反过来。
两个数组的交集leetcode-cn.com
给定两个数组,编写一个函数来计算它们的交集。
#输入:nums1 = [1,2,2,1], nums2 = [2,2]
#输出:[2]
可以先将两个数组去重,也就是直接加入到set里;然后再求两个set的交集,再python里直接使用&即可。题目中的注意事项里已经说明都是唯一元素。
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
return (set(nums1)&set(nums2))
两个数组的交集 IIleetcode-cn.com
给定两个数组,编写一个函数来计算它们的交集。
#输入:nums1 = [1,2,2,1], nums2 = [2,2]
#输出:[2,2]
说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。我们可以不考虑输出结果的顺序。
进阶:
如果给定的数组已经排好序呢?你将如何优化你的算法?如果 nums1 的大小比 nums2 小很多,哪种方法更优?如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
这里允许出现重复数字,因此不能再使用集合set;但是可以使用Hash表,那么最后相交的元素则应该是出现次数少的那么多次即可。利用defaultdict:
from collections import defaultdict as dt
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
x = dt(int)
y = dt(int)
res = []
for i in nums1:
x[i] += 1
for i in nums2:
y[i] += 1
for i in x:
res += [i for j in range(min(y[i], x[i]))]#看看有多少个重复的相同的元素
return res
利用collections里的Counter函数:
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
num1 = collections.Counter(nums1)
num2 = collections.Counter(nums2)
num = num1 & num2
return num.elements()
1.如果是排序好的
#对于排好序的则去掉排序函数
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
nums1.sort()
nums2.sort()
length1, length2 = len(nums1), len(nums2)
ans = list()
index1, index2 = 0, 0
while index1 < length1 and index2 < length2:
if nums1[index1] == nums2[index2]:
ans.append(nums1[index1])
index1 += 1
index2 += 1
elif nums1[index1] < nums2[index2]:
index1 += 1
else:
index2 += 1
return ans
结语:
如果的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中。那么就无法高效地对
进行排序,因此推荐使用字典的方法而不是排序的方法。字典方法中,
只关系到查询操作,因此每次读取
中的一部分数据,并进行处理即可。