代码随想录算法训练营第六天||454.四数相加II 、383. 赎金信、15. 三数之和、18. 四数之和

LeetCode 454.四数相加II 

题目/视频/文章链接:

454.四数相加||

个人第一时间看法:

考虑到之前做过的两数之和,得用哈希表来解决,只不过对于四个数组的操作有点懵,感觉无从下手,只想到四个for循环暴力解决。

看完代码随想录的想法:

鉴于两数之和的操作,可以将四个数组分成两大组来进行操作,而且这道题不需要考虑重复情况,所以继续用map的结构体。

敲代码时遇到的困难:

满足条件的数组数量应该用前一个大组出现过的次数进行相加,一开始没意识到直接+1了,导致结果数量对应不上。

实际代码:

class Solution(object):
    def fourSumCount(self, nums1, nums2, nums3, nums4):
        # use a dict to store the elements in nums1 and nums2 and their sum
        hashmap = dict()
        for n1 in nums1:
            for n2 in nums2:
                if n1 + n2 in hashmap:
                    hashmap[n1+n2] += 1
                else:
                    hashmap[n1+n2] = 1
        
        # if the -(a+b) exists in nums3 and nums4, we shall add the count
        count = 0
        for n3 in nums3:
            for n4 in nums4:
                key = - n3 - n4
                if key in hashmap:
                    count += hashmap[key]
        return count

LeetCode 383. 赎金信

题目/视频/文章链接:

383.赎金信

个人第一时间看法:

这和之前做过的字母异位词大同小异,直接用数组的结构来解题即可

看完代码随想录的想法:

这就是一道最基础的哈希表操作题

敲代码时遇到的困难:

没什么难度,能敲出字母异位词的代码,这道题也不在话下

实际代码:

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:

        arr = [0] * 26

        for x in magazine:    # 记录 magazine里各个字符出现次数
            arr[ord(x) - ord('a')] += 1

        for x in ransomNote:  # 在arr里对应的字符个数做--操作
            if arr[ord(x) - ord('a')] == 0:  # 如果没有出现过直接返回
                return False
            else:
                arr[ord(x) - ord('a')] -= 1
        
        return True

LeetCode 15. 三数之和

题目/视频/文章链接:

15.三数之和

个人第一时间看法:

懵逼,三个数没办法像之前的四数相加分成两个大组来解题,而且还不能重复,想到set结构体可以不重复,但是三个数该咋用set来遍历呢,挠挠头

看完代码随想录的想法:

既然不需要返回下标,那就可以先进行排序,进而这道题最适方法不是用哈希表,而是用双指针的方法来进行操作,一个从头开始遍历,后两个从两边进行遍历,分清楚什么情况下该移动哪个指针,然后这三个指针都需要进行去重操作,这是个重难点。

敲代码时遇到的困难:

在从头遍历的那个指针进行去重操作时,出现了差错,应该将当前指针的位置与前一个位置进行对比去重,若是对后一个进行对比的话容易漏掉可行结果。

实际代码:

class Solution:
    def threeSum(self, nums):
        ans = []
        n = len(nums)
        nums.sort()
	# 找出a + b + c = 0
        # a = nums[i], b = nums[left], c = nums[right]
        for i in range(n):
            left = i + 1
            right = n - 1
	    # 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
            if nums[i] > 0: 
                break
            if i >= 1 and nums[i] == nums[i - 1]: # 去重a
                continue
            while left < right:
                total = nums[i] + nums[left] + nums[right]
                if total > 0:
                    right -= 1
                elif total < 0:
                    left += 1
                else:
                    ans.append([nums[i], nums[left], nums[right]])
		    # 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
                    while left != right and nums[left] == nums[left + 1]: left += 1
                    while left != right and nums[right] == nums[right - 1]: right -= 1
                    left += 1
                    right -= 1
        return ans
LeetCode 18. 四数之和

题目/视频/文章链接:

18.四数之和

个人第一时间看法:

基于四数相加和三数之和的思路,既然不需要返回下标,那就可以先排序,进而可以运用双指针,在三个指针的基础上,再在左端加一个指针,前两个为一组,后两个为一组进行操作,挨个遍历从而实现四数之和应该就可以。

看完代码随想录的想法:

只不过这道题给的要求不是0而是target,这样的话在开头判断的时候就有更多的细节了,不只是去重还得剪枝,需要好好琢磨。

敲代码时遇到的困难:

在开头的剪枝操作有点生疏,再就是第二个指针要在第一个指针的基础上进行剪枝去重,得多加熟练才行。

实际代码:

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        
        nums.sort()
        n = len(nums)
        res = []
        for i in range(n):   
            if i > 0 and nums[i] == nums[i - 1]: continue  # 对nums[i]去重
            for k in range(i+1, n):
                if k > i + 1 and nums[k] == nums[k-1]: continue  # 对nums[k]去重
                p = k + 1
                q = n - 1

                while p < q:
                    if nums[i] + nums[k] + nums[p] + nums[q] > target: q -= 1
                    elif nums[i] + nums[k] + nums[p] + nums[q] < target: p += 1
                    else:
                        res.append([nums[i], nums[k], nums[p], nums[q]])
			# 对nums[p]和nums[q]去重
                        while p < q and nums[p] == nums[p + 1]: p += 1
                        while p < q and nums[q] == nums[q - 1]: q -= 1
                        p += 1
                        q -= 1
        return res

今日收获:

今天第一道题也是运用了map的结构进行操作,整体的思路就是看看能不能构成两个组,从而进行哈希表操作解题,第二题就是跟之前的题目进行变式训练而已,熟练操作,第三四题巧妙的运用题目要求,进行排序从而可以使用双指针法进行解题,而且其中的剪枝去重操作格外需要注意细节,仍需多多磨练!今日学习时长2h!
 

你可能感兴趣的:(数据结构,python,算法,哈希算法)