首页 > 其他分享 >巧用hash; 双指针法 | 刷题第7天 | 454.四数相加II, 383. 赎金信, 15. 三数之和, 18. 四数之和

巧用hash; 双指针法 | 刷题第7天 | 454.四数相加II, 383. 赎金信, 15. 三数之和, 18. 四数之和

时间:2022-11-01 14:47:38浏览次数:75  
标签:四数 end nums 三数 mid len while hash first

Problem: 454. 四数相加 II

思路

讲述看到这一题的思路

  • 思考: 如何用map有效节省时间

想一想: 题目1.两数之和, 用的map

  • 推广: 可以时间O(n^3),空间O(n)

map: key=sum123, val=times

  • 推广: 时间O(n^2), 空间O(n^2)

两两构建map: key=sum12, val=times

遍历一个map, 检索另一个

  • 优化: 时间O(n^2), 空间O(n^2)

构建1个map: key=sum12, val=times

遍历一个map, 检索另一个

知识补充

  • 补充: dict.get(key, 缺省值)

Code


class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        
        m = {} # 存储

        # 遍历nums1和nums2构建map
        for i in nums1:
            for j in nums2:
                if i+j not in m:
                    m[i+j] = 1
                else:
                    m[i+j] += 1
                    
        n = 0
        # 遍历nums3和nums4并且检索map
        for i in nums3:
            for j in nums4:
                n += m.get(-i-j, 0) # 补充: dict.get(key, 缺省值)

        return n

Problem: 383. 赎金信

思路

讲述看到这一题的思路

用len=26的数组l: idx表示alpha, val表示个数

遍历magazine, 得到l

遍历ransomNote, 对应l项--, 若对应项为0则false

复杂度

  • 时间复杂度:

添加时间复杂度, 示例: $O(n)$

  • 空间复杂度:

添加空间复杂度, 示例: $O(n)$

Code

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        # 用len=26的数组l: idx表示alpha, val表示个数
        # 遍历magazine, 得到l
        # 遍历ransomNote, 对应l项--, 若对应项为0则false

        # 构建hash
        l = [0] * 30
        for ch in magazine:
            l[ord(ch) - ord('a')] += 1
        
        # 检索
        for ch in ransomNote:
            if l[ord(ch) - ord('a')] > 0:
                l[ord(ch) - ord('a')] -= 1
            else: 
                return False
        
        return True

Problem: 15. 三数之和

时间
644 ms
击败
70.10%
内存
18 MB
击败
21.40%

思路

讲述看到这一题的思路

思路: 双指针, 时间O(n^2)

  1. 进行排序

  2. 双指针: first,mid,end

    遍历first, 向后移动mid或者向前移动end

    重点:如何去重

     因为已经sort
     所以可以直接通过移动, 排除掉连续相同的数
    

复杂度

  • 时间复杂度:

添加时间复杂度, 示例: $O(n^2)$

  • 空间复杂度:

添加空间复杂度, 示例: $O(n)$

Code


class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # 思路: 双指针, 时间O(n^2)
        # 1.进行排序
        # 2.双指针: first,mid,end
        #   遍历first, 向后移动mid或者向前移动end
        #   重点:如何去重
        #       因为已经sort
        #       所以可以直接通过移动, 排除掉连续相同的数

        # 先进行排序
        nums.sort()
        print(nums)

        l = []

        # 遍历
        first = 0
        while first < len(nums) - 2:
            if nums[first] > 0: # 因为非递减 => first大于0, 不可能总和等于0
                return l

            # 初始化双指针
            mid = first + 1
            end = len(nums) - 1

            while end > mid:
                # 移动双指针
                if nums[first]+nums[mid]+nums[end] < 0:
                    mid += 1
                    continue
                if nums[first]+nums[mid]+nums[end] > 0:
                    end -= 1
                    continue
                
                if nums[first]+nums[mid]+nums[end] == 0:
                    print("find:",first,mid,end)
                    # 在找到3元组之后再进行去重
                    while end > 0 and nums[end] == nums[end - 1]:
                        end -= 1
                    while mid < len(nums)-1 and nums[mid] == nums[mid + 1]:
                        mid += 1
                    l.append([nums[first],nums[mid],nums[end]])
                    # 共同向中间移动
                    mid += 1
                    end -= 1
            
            # 对于first进行去重
            while first < len(nums)-1 and nums[first] == nums[first + 1]:
                first += 1
            first += 1

        return l

Problem: 18. 四数之和

Code


class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums.sort()
        l = []
        i = 0
        while i < len(nums)-3:
            print()
            print("i=",i)
            if nums[i] > 0 and nums[i] > target: # 剪枝
                return l
            j = i+1
            while j < len(nums)-2:
                if nums[i]+nums[j] > 0 and nums[i]+nums[j] > target: # 剪枝
                    break
                left = j+1
                right = len(nums)-1

                # 双指针
                while left < right:
                    if nums[i]+nums[j]+nums[left]+nums[right] > target:
                        right -= 1
                        continue
                    elif nums[i]+nums[j]+nums[left]+nums[right] < target:
                        left += 1
                        continue
                    else: # 找到了, 进行去重
                        l.append([nums[i],nums[j],nums[left],nums[right]])
                        while left < len(nums)-1 and nums[left] == nums[left+1]:
                            left += 1
                        while right > left and nums[right] == nums[right-1]:
                            right -= 1
                        left += 1
                        right -= 1
                    
                # j去重
                while j < len(nums)-1 and nums[j] == nums[j+1]:
                    j += 1
                j += 1
            
            # i去重
            while i < len(nums)-1 and nums[i] == nums[i+1]:
                i += 1
            i += 1
        
        return l         

标签:四数,end,nums,三数,mid,len,while,hash,first
From: https://www.cnblogs.com/ywh-pku/p/16847606.html

相关文章

  • 为什么重写equals一定要重写hashCode方法?
    分享知识传递快乐  equals方法和hashCode方法都是Object类中的方法。equals方法在其内部是调用了"==",所以说在不重写equals方法的情况下,equals方法是比较两个对象是否具......
  • HashMap初始化容量
    HashMap初始化容量《阿里巴巴Java开发规约》中有提到:【推荐】集合初始化时,指定集合初始值大小。说明:HashMap使用如下构造方法进行初始化,如果暂时无法确定集合大小,那么指定......
  • HashSet实现类的使用
    【1】放入Integer类型数据packagecom.msb.test06;importjava.util.HashSet;/***@author:liu*日期:10:36:57*描述:IntelliJIDEA*版本:1.0*/publi......
  • 一致性Hash算法
    一致性Hash算法为什么使用一致性Hash我们在使用Redis的时候,为了保证Redis的高可用,提高Redis的读写性能,最简单的方式我们会做主从复制,组成Master-Master或者Master-Slave的形......
  • LeetCode_16. 最接近的三数之和
    题目描述:给定一个包括n个整数的数组nums和一个目标值target。找出nums中的三个整数,使得它们的和与target最接近。返回这三个数的和。假定每组输入只存在唯一答案......
  • 2022祥云杯 - HashRun安全团队wp
    2022祥云杯-HashRun安全团队wpHaveFun@T4x0r注册一个\(admin\)账号发现页面会提示已经注册,其实本来想的是注入,但是发现注册功能活的,感觉二次注入可能也不是很大,注册......
  • 关于hashMap的容量为什么是2的幂次方数
    先看hashMap的构造方法publicHashMap(intinitialCapacity,floatloadFactor){if(initialCapacity<0)thrownewIllegalArgumentException(......
  • HashMap详解
    HashMap详解HashMap相关介绍HashMap是Java中的比较常见的集合,主要存放的是键值对,以key-value的形式存储,不是线程安全的。它里面的存储的key和value可以为null值,但是key......
  • hash的应用
    hash可以看成对一串较长信息的压缩和加密,在OI中多用来比较字符串是否相同,然而hash的应用其实可以有很大拓展,比如想要维护全局信息是否处于某种特殊形态,具体来讲,以一个最近......
  • LeetCode15. 三数之和
    题意找出数组中三个和为0的数字方法哈希表代码classSolution{public:vector<vector<int>>threeSum(vector<int>&nums){vector<vector<int>>resu......