leetcode练习 532 python实现(字典方式和二分搜索)

题532

题目要求在一个list中寻找差为固定值的pair的数量,具体如下:
Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an integer pair (i, j), where i and j are both numbers in the array and their absolute difference is k.

Example 1:
Input: [3, 1, 4, 1, 5], k = 2
Output: 2
Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5).
Although we have two 1s in the input, we should only return the number of unique pairs.
Example 2:
Input:[1, 2, 3, 4, 5], k = 1
Output: 4
Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5).
Example 3:
Input: [1, 3, 1, 5, 4], k = 0
Output: 1
Explanation: There is one 0-diff pair in the array, (1, 1).
Note:
The pairs (i, j) and (j, i) count as the same pair.
The length of the array won’t exceed 10,000.
All the integers in the given input belong to the range: [-1e7, 1e7].

这个结果是很好实现的,但是会发现时间复杂度始终是O(n2),所以始终通过不了。后来利用python中的字典HashMap的思想,查找键值只需要O(1)的复杂度,对程序进行了改进,效果明显提升。
我的思路是:
1.K<0,返回0
2.K=0,先对nums进行set,找到不重复的元素,再对这些元素遍历,count它们出现的次数,若>1,说明有一个符合要求,sum+=1,最后返回sum
3.K>0, 先对nums进行set,以及sorted排序,for循环,建立一个dict,它的key是当前数nums[i]+k,它的值是nums[i],然后判断当前nums[i]是不是之前出现的某个数的key,若是,则出现了一对符合要求的pair,sum+=1,最后返回sum。

代码如下:

class Solution:
    def findPairs(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """

        sum =0
        nu= {}
        if k<0:
            return 0
        if k!=0:
            nums = list(set(nums))
            nums = sorted(nums)
            for i in range(len(nums)):
                nu[nums[i]+k] = nums[i]
                if nums[i] in nu.keys():
                    sum+=1
            return sum
        else:
            nums1 = list(set(nums))
            for i in nums1:
                if nums.count(i)>1:
                    sum+=1
            return sum
nums=[1,1,1,2,1]
k=1
s= Solution()
print(s.findPairs(nums,k))

结果如下:
这里写图片描述

Accept结果:
这里写图片描述

思路2 二分查找

我的思路是:重要的一点是用二分搜索寻找nums[i]+k降低时间复杂度,同时分k=0和k!=0的情况具体分析。
k=0时,需要找相等的数字对,重点是一个去重的实现。
k!=0时的去重,只要之前遇到的相同的数就continue掉,并且在找到第一个符合条件的nums[i]后就continue,不再继续寻找。

具体代码如下:

class Solution:
    def findPairs(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        if len(nums)==0:
            return 0
        nums.sort()
        sum = 0
        s = nums[0]
        flag = 0

        if k ==0:
            for i in range(len(nums)):
                if k == 0:
                    if i > 0 and nums[i] == s:
                        flag = 1
                    if (flag == 1 and nums[i] != s) or (flag ==1 and i==len(nums)-1):
                        flag = 0
                        s = nums[i]
                        sum += 1
            return sum

        if k != 0:
            for i in range(len(nums)-1):
                if i > 0 and nums[i] == nums[i - 1]:
                    continue
                left = i
                right = len(nums)
                while (left <= right):
                    mid = int((left + right) / 2)
                    if mid < len(nums):
                        if nums[i] + k > nums[mid]:
                            left = mid + 1
                        if nums[i] + k < nums[mid]:
                            right = mid - 1
                        if nums[i] + k == nums[mid]:
                            sum += 1
                            break
                    else:
                        break
            return sum


nums=[1,1,1,1,1,2,2,2]
k=0
s= Solution()
print(s.findPairs(nums,k))

最终也能Accept

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值