LeetCode Q16-Q20练习笔记 (Python3)

这篇博客详细记录了LeetCode中Q16-Q20的解题思路,包括3Sum Closest、Letter Combination of a Phone Number、4Sum、Remove Nth Node from End of List和Valid Parentheses。对于每个问题,作者分享了自己的解法和遇到的难点,还引用了其他高效解决方案,强调了递归、链表操作和字符串处理的关键点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Q16 最接近的三数之和 3Sum Closest

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

这道题和3Sum没什么太大的区别,把目标值0换成了target,最后也是用双指针然后解决的这道题

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        minDif=2**31-1
        for i in range(len(nums)):
            left=i+1
            right=len(nums)-1
            
            while left<right:
                if abs((nums[i]+nums[left]+nums[right])-target)<minDif:
                    sol=nums[i]+nums[left]+nums[right]
                    minDif=abs((nums[i]+nums[left]+nums[right])-target)
                if nums[i]+nums[left]+nums[right]<target:
                    left+=1
                elif nums[i]+nums[left]+nums[right]>target:
                    right-=1
                else:
                    return target
        return sol

Q17 电话号码的字母组合 Letter Combination of a Phone Number

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。在这里插入图片描述

这道题我用的是递归的方法,由于很久没有使用递归,我在这上面花了一些时间

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if digits=="":
            return []
        lst_letter={"2":"abc","3":"def","4":"ghi","5":"jkl","6":"mno","7":"pqrs","8":"tuv","9":"wxyz"}
        lst_sol=[""]

        def returnLetter(digits,lst_sol):
            if not digits: #终止递归
                return lst_sol
            lst=[]
            for i in range(len(lst_sol)):
                for j in range(len(lst_letter[digits[0]])):
                    lst.append(lst_sol[i]+lst_letter[digits[0]][j])
            lst_sol=lst

            return returnLetter(digits[1:],lst_sol)

        return returnLetter(digits,lst_sol)

需要注意的是递归一定要有个跳出的判断,不然会陷入死循环,这个方法很明显并不高效,但是这是我对这种题目的一个下意识的思路,高效的解法是摘自一个大神的:

class Solution:
    def letterCombinations(self, digits: str) -> list:
        KEY = {'2': ['a', 'b', 'c'],
               '3': ['d', 'e', 'f'],
               '4': ['g', 'h', 'i'],
               '5': ['j', 'k', 'l'],
               '6': ['m', 'n', 'o'],
               '7': ['p', 'q', 'r', 's'],
               '8': ['t', 'u', 'v'],
               '9': ['w', 'x', 'y', 'z']}
        if digits == '':
            return []
        ans = ['']
        for num in digits:
            ans = [pre+suf for pre in ans for suf in KEY[num]]
        return ans

他厉害的地方在于用了python中for循环在字符串和列表的应用,直接遍历了每一个字符串再让它们相加,可以学一下,因为之前在其他语言中并不会想到

Q18 四数之和 4Sum

不写了,太恶心了,来个NSum得了

Q19 删除链表的倒数第 N 个结点 Remove Nth Node from End of List

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?

链表的使用确实还不太熟悉,这道题废了半天的劲也是写出来了,只是我用的方法是遍历两次,先得出链表的长度,再根据长度减去n获得正序的索引位置进而删除,太麻烦了。
下面这个是看的别人写的,它先用了一个链表a遍历到第n个节点,然后再与b同时遍历直到a遍历完成,这时候b的下一个节点便是倒数第n个节点,🐂🍺

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        a = head
	    b = head
	    
	    for i in range(n):
	        if a.next:
	            a = a.next
	        else:
	            return head.next
	            
	    while a.next:
	        a = a.next
	        b = b.next
	    b.next = b.next.next
	    return head

链表中需要着重注意的是要知道遍历的条件(通常为b.next不为空时),除此之外也需要注意若是要改变节点的链接,需要让b.next受到改变,如b.next = b.next.next,而不是让当前节点b=b.next.next,这只会发生指针跳转而不会改变节点。

Q20 有效的括号 Valid Parentheses

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

怎么说呢,用了正则表达式写了半天(虽然这个想法从一开始就不太好用),不如别人的灵机一动,这种种类不多的固定字符串形式感觉都可以用这种方法来写。

class Solution:
    def isValid(self, s: str) -> bool:
        while '{}' in s or '()' in s or '[]' in s:
            s = s.replace('{}', '')
            s = s.replace('[]', '')
            s = s.replace('()', '')
        return s == ''

它无数次遍历找寻三种括号的集合直到找不到为止,每找到一次就替换为空格,最后符合标准的字符串将全部转为空格,直接返回判断值就行。我能说啥呢,🐂🍺

Q16-Q20 一些笔记

  1. 递归的时候不要忘记跳出的语句

  2. 类下的方法中的方法可以不用在参数中加self

  3. for循环可以用于字符串与列表,如Q17:

    ans = ['']
    for num in digits: #for在字符串中遍历
    	ans = [pre+suf for pre in ans for suf in KEY[num]] #for在字符串与列表中遍历
    
  4. 若要改变链表的节点连接,需要让b.next受到改变,如b.next = b.next.next,而不是让当前节点b=b.next.next,这只会让指针跳到下下个节点而不会改变节点的链接。

  5. head是链表的第一个元素,使b=head,遍历b时不会让head发生改变。若想改变head,参照第四条笔记,让b.next发生改变,使得链表节点链接改变

  6. Q20这种替换字符串的方法适用于一些找特定字符串组合的题目,多留意一下这种方法吧
    再多写一些链表题目吧,把速度加快一些,有时候刷题会让自己越来越灰心,觉得自己总是想不到最好的解决方法,但是没办法,加油干吧。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值