java stream 分别统计多列 java list count_java stream 分别统计多列


不见五陵豪杰墓,无花无酒锄作田。《唐伯虎点秋香》

计算右侧小于当前元素的个数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


结语:

如果的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中。那么就无法高效地对

进行排序,因此推荐使用字典的方法而不是排序的方法。字典方法中,

只关系到查询操作,因此每次读取

中的一部分数据,并进行处理即可。