【每日一题】【LeetCode】【第二十四天】【Python】两个数组的交集 II

解决之路= =

题目描述

在这里插入图片描述

测试案例(部分)

在这里插入图片描述

第一次

顺着“两个数组的交集”的思路想,先用集合处理nums1nums2,然后通过“交集”运算得出列表res,然后循环检查列表res,得出各个元素在两个数组中出现的最小次数,最终在列表plus中添上少的元素,借助python的列表相加,返回res+plus就是答案。

class Solution(object):
    def intersect(self, nums1, nums2):
        res = list(set(nums1) & set(nums2))
        plus = []
        for i in res:
            s = min(nums1.count(i), nums2.count(i))
            for j in range(s - 1):
                plus.append(i)
        return res + plus

测试正确,提交通过。不过,效率不高。

在这里插入图片描述

第二次

想一想如何优化。在进阶提示中,第一条就是有序的两个数组会怎么优化算法。

看了看评论区,有人在两个有序数组的基础上再用双指针法进行遍历(假设是p1p2两个指针,各自从nums1nums2开始找),如果相同p1p2一起+1,不相同时,哪边小了哪边+1,这样不但可以控制多次加入同样的元素,还保证了时间复杂度是O(m+n)。

按照这个思路我们来实现一下,转化成代码比较简单。

class Solution:
    def intersect(self, nums1, nums2):
        nums1.sort()
        nums2.sort()
        p1, p2 = 0, 0
        res = []
        while p1 < len(nums1) and p2 < len(nums2):
            if nums1[p1] == nums2[p2]:
                res.append(nums1[p1])
                p1 += 1
                p2 += 1
            else:
                if nums1[p1] < nums2[p2]:
                    p1 += 1
                else:
                    p2 += 1
        return res

测试正确,提交成功!

在这里插入图片描述

可以说,双指针法不一定局限于一个数据中使用。一个数组可以一前一后,然后夹住我们最终需要的结果;两个数组可以一个数组一个,从头到尾相互比对。

前面有题目也表示了双指针可以应用于有序数组也可以应用于无序,所以双指针法有灵活一点,针对需求,有时会有奇效。

杂谈

前面写很多题的时候,很多时候都看到了动态规划这个思想,不过试着用这个代码跑了跑,花费5512 ms时间。。。太慢了,思路也没怎么看懂,看看以后的题目能不能练一下吧。

"""动态规划"""
class Solution:
    def intersect(self, nums1, nums2):
        nums1 = sorted(nums1)
        nums2 = sorted(nums2)
        dp = [[[]] * (len(nums2)+1) for _ in range(len(nums1)+1)]
        for i in range(1, len(nums1)+1):
            for j in range(1, len(nums2)+1):
                if nums1[i-1] == nums2[j-1]:
                    dp[i][j] = dp[i-1][j-1] + [nums1[i-1]]
                else:
                    dp[i][j] = max(dp[i][j-1], dp[i-1][j], key=len).copy()
        return dp[-1][-1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值