首页 > 编程语言 >代码随想录算法训练营第七天|leetcode454.四数相加II、leetcode383. 赎金信 、leetcode15. 三数之和、leetcode18.四数之和

代码随想录算法训练营第七天|leetcode454.四数相加II、leetcode383. 赎金信 、leetcode15. 三数之和、leetcode18.四数之和

时间:2024-10-22 12:35:44浏览次数:7  
标签:四数 hashmap nums int 随想录 recorde List leetcode454 ord

1 leetcode454.四数相加II

题目链接:454. 四数相加 II - 力扣(LeetCode)

文章链接:代码随想录

视频链接:学透哈希表,map使用有技巧!LeetCode:454.四数相加II_哔哩哔哩_bilibili

自己的思路:第一反应就是暴力搜索,一层一层for循环来完成,就是会超时

1.1 自己的代码

纯纯暴力搜索

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        count = 0
        for i in nums1:
            for j in nums2:
                for k in nums3:
                    for l in nums4:
                        if i+j+k+l == 0:
                            count +=1
        return count

1.2 哈希表的方法

1.2.1哈希表未调用函数

之前出错的一个地方,如果查询的键未在函数内部,则需要建立一个键以及所对应的值

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        hashmap = dict()
        count = 0
        for i in nums1:
            for j in nums2:
                if i+j in hashmap:
                    hashmap[i+j] +=1
                else :
                    hashmap[i+j] = 1
        for k in nums3:
            for l in nums4:
                num = 0-(k+l)
                if num in hashmap:
                    count += hashmap[num]
        return count
1.2.2 使用get函数

之前会,但是没用过,今儿深切感受到了,其使用方法就是在字典内部看看对应的键的位置,没有就是获得一个键和值,值为0

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        hashmap = dict()
        count = 0
        for i in nums1:
            for j in nums2:
                hashmap[i+j] = hashmap.get(i+j,0)+1
        for k in nums3:
            for l in nums4:
                num = 0-(k+l)
                if num in hashmap:
                    count += hashmap[num]
        return count

1.3 本题小结

  1. 这道题很巧妙的地方就是如何求值,先将两个数组的值进行存储在一个字典中,然后用目标值减去另外两个数组的值得到一个值,然后这个值在字典中查找,这样时间复杂度只有n的平方了
  2. 在一个空字典中加键值对的方法,一种就是直接判断,不在里面就直接num[key] = 1或者就是num[key] = num.get(key,0)+1

2 leetcode 383. 赎金信

题目链接:383. 赎金信 - 力扣(LeetCode)

文章链接:代码随想录

自己的思路:

  1. 字符串总共有26个,所以建立一个可以容纳26个字符串的哈希表,初始值为0
  2. 统计第一个字符串s中每个字母出现的次数,这里计算就是用字符串位置减去第一个字母即'a'的值,计算两个字符串的值在python中转化为对ASCII码计算,函数是ord(),然后就是统计每个字符串出现的次数,对其数值进行相加
  3. 对第二个字符串t中的数据对哈希表进行一个减法的操作
  4. 对字符串中的字符进行循环,如果哈希表的值有小于0的,则证明两个字符串不相等,否则就是相等

2.1 自己的代码

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        recorde = [0]*26
        for i in magazine:
            recorde[ord(i)-ord('a')] +=1
        for j in ransomNote:
            recorde[ord(j)-ord('a')] -=1
        for k in range(26):
            if recorde[k] < 0:
                return False
        return True

2.2 哈希表的方法

看了别人的方法,觉得这道题的代码可以简单一点

2.2.1 数组的方法
class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        recorde = [0]*26
        for i in magazine:
            recorde[ord(i)-ord('a')] +=1
        for j in ransomNote:
            recorde[ord(j)-ord('a')] -=1
            if recorde[ord(j)-ord('a')] < 0:
                return False
        return True
2.2.2 字典的方法

字典的方法也是在随想录里面学习到的,发现这个方法真的很巧妙,就是如果目标键不在我们的字典中或者在字典中值为0,就代表没有

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        recorde = dict()
        for i in magazine:
            recorde[i] = recorde.get(i,0)+1
        for j in ransomNote:
            if j not in recorde or recorde[j] == 0:
                return False
            recorde[j] -=1
        return True

2.3 本题小结

  1. 这道题的基本思想和第一个哈希表的方法很相似,而且做法几乎一样
  2. 使用字典的时候,一定要注意键值对的值小于0会报错

3 leetcode15. 三数之和

题目链接:15. 三数之和 - 力扣(LeetCode)

文章链接:代码随想录

视频链接:梦破碎的地方!| LeetCode:15.三数之和_哔哩哔哩_bilibili

自己的思路:原计划是使用字典来存储,然后算一个值出来,如果这个值在字典里面并且和循环中的值不同,则进行输出,发现做的时候会有重复的

3.1视频后的思路

使用双指针的方法,就是不断去判断,感觉双指针的思路时间就比较久,但是结果还算比较好的,就是要去判断有没有相同的数,如果出现了就要往后面移动一位,这个点没想通开始的时候

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        result = []
        nums.sort()
        for i in range(len(nums)):
            if nums[i]>0:
                return result
            if i>0 and nums[i]==nums[i-1]:
                continue
            left = i+1
            right = len(nums)-1
            while left<right:
                if nums[i]+nums[left]+nums[right] >0:
                    right -=1
                elif nums[i]+nums[left]+nums[right] <0:
                    left +=1
                else:
                    result.append([nums[i],nums[left],nums[right]])
                    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 result

3.2本题小结

  1. 感觉这道题难点就在于去重,还有就是判断有0以后,后面的while语句要有两个条件,分开写也不是不行,就是时间会变长
  2. 主要就是需要去重,返回的是值而不是下标,下标重复无所谓,但是不能让值重复

4 leetcode18.四数之和

题目链接:18. 四数之和 - 力扣(LeetCode)

文章链接:代码随想录

视频链接:难在去重和剪枝!| LeetCode:18. 四数之和_哔哩哔哩_bilibili

自己的思路:这道题才开始真的没思路,因为今天感觉自己很烦躁,一直做不好题,看了里面的讲解以后,说再嵌套一层循环即可

4.1 双指针的思路

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums.sort()
        result = []
        for i in range(len(nums)):
            if nums[i]>target and nums[i]>=0:
                break
            if i>0 and nums[i]==nums[i-1]:
                continue
            for k in range(i+1,len(nums)):
                if nums[i]+nums[k]>target and nums[i]+nums[k]>=0:
                    break
                if k>i+1 and nums[k] == nums[k-1]:
                    continue
                left = k+1
                right = len(nums)-1
                while left<right:
                    sum_ = nums[i]+nums[k]+nums[left]+nums[right]
                    if sum_<target:
                        left +=1
                    elif sum_>target:
                        right -=1
                    else:
                        result.append([nums[i],nums[k],nums[left],nums[right]])
                        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 result

4.2 本题小结

  1. 其实这道题真的和三数之和超级超级像,感觉没有任何区别
  2. 就是有一个去重的操作,必须nums>=target的时候,还有就是target>0,因为如果小于0也会出现问题

5 本章小结

  1. 其实这个地方很重要的一点,就是不能陷入整个哈希表里面,因为题目是多源的,就是只要能做就好,不要陷入进去
  2. 在空字典里面添加键值对的方法,就是nums[a]=nums.get(a,0)

标签:四数,hashmap,nums,int,随想录,recorde,List,leetcode454,ord
From: https://www.cnblogs.com/csfy0524/p/18492368

相关文章

  • 代码随想录算法训练营Day39 | 卡玛网-46.携带研究材料、416. 分割等和子集
    目录卡玛网-46.携带研究材料416.分割等和子集卡玛网-46.携带研究材料题目卡玛网46.携带研究材料(第六期模拟笔试)题目描述:小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。他需要带一些研究材料,但是他的行李箱空间有限。这些研究材料包......
  • 代码随想录算法训练营第六天| leetcode242.有效的字母异位词、leetcode349.两个数组的
    1.leetcode242.有效的字母异位词题目链接:242.有效的字母异位词-力扣(LeetCode)文章链接:代码随想录视频链接:学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词_哔哩哔哩_bilibili自己的思路:首先就是对字符串进行分开成一个一个单独的字母,然后使用列表存储这些数据,再对......
  • 代码随想录算法训练营 | 739. 每日温度,496.下一个更大元素 I ,503.下一个更大元素II
    739.每日温度题目链接:739.每日温度文档讲解︰代码随想录(programmercarl.com)视频讲解︰每日温度日期:2024-10-20想法:遍历一遍数组,用栈来存数组下标做记录,因为要找更高得温度,当当前遍历的温度大于栈头存储(存的下标)的温度时,就可以知道栈头要过多少天遇到高温,低的时候直接入栈。J......
  • 代码随想录算法训练营第五天| 面试题02.07.链表相交、leetcode142 环形链表II
    1.leetcode面试题02.07.链表相交题目链接:面试题02.07.链表相交-力扣(LeetCode)文章链接:代码随想录1.1代码跟着老师写的一个版本,自己能理解思路了,但是写的话可能还是有一些难#Definitionforsingly-linkedlist.#classListNode:#def__init__(self,x):#......
  • 代码随想录|回溯part 01
    存在于递归函数的下方,递归与回溯相辅相成回溯搜索法:暴力算法适用范围:•组合问题:N个数里面按一定规则找出k个数的集合(无序)•切割问题:一个字符串按一定规则有几种切割方式•子集问题:一个N个数的集合里有多少符合条件的子集•排列问题:N个数按一定规则全排列,有几种排列方......
  • 代码随想录算法训练营day20| 669. 修剪二叉搜索树 108.将有序数组转换为二叉搜索树
    学习资料:https://programmercarl.com/0669.修剪二叉搜索树.html#算法公开课学习记录:669.修剪二叉搜索树(直接在原函数上操作,要根据情况用root的左右子树递归,因为子树中有满足条件的;前序:根左右)点击查看代码#Definitionforabinarytreenode.#classTreeNode:#def_......
  • 代码随想录算法训练营 | 647. 回文子串,516.最长回文子序列
    647.回文子串题目链接:647.回文子串文档讲解︰代码随想录(programmercarl.com)视频讲解︰回文子串日期:2024-10-19想法:本题精髓在于dp[i][j]表示的是s[i,j]这个子字符串是不是回文的,是Boolean类型,s[i]s[j]不等时,肯定不回文;s[i]s[j]相等时,开始看ij的大小,ij大小相等那么表示单个字......
  • 代码随想录算法训练营第四天| 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点
    1.leetcode24两两交换链表中的节点题目链接:24.两两交换链表中的节点-力扣(LeetCode)文章链接:代码随想录(programmercarl.com)视频链接:帮你把链表细节学清楚!|LeetCode:24.两两交换链表中的节点_哔哩哔哩_bilibili1.1代码这个代码是用循环的思路来进行判断的,写的过程挺......
  • 代码随想录打卡Day2
                                                                                                                                   ......
  • 代码随想录打卡Day3
    链表:通过指针链接的线性数据结构。链表由两部分组成,一为数据域,一为指针域。并与结构体有很大关系,链表的节点一般都是结构体,其中包含了该节点的数据部分以及指向下一节点的指针。通过这种方式,链表将结构体与指针连接起来,从而构建一个强大的数据结构,可以同时实现数据的组织和动......