第四次

本文解析了LeetCode中的三个问题,涉及链表合并、括号有效性检查和三数之和最接近。通过递归和栈的数据结构,展示了如何高效解决这些问题。

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

题目1

  • 题号:16
  • 难度:中等
  • https://leetcode-cn.com/problems/3sum-closest/

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

示例 :

例如,给定数组 nums = [-121-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

思路1

这题和三数之和接近,就是排序然后再使用双指针。寻找最接近的数,刚好原来的三数之和就是使用慢慢接近的方法寻找target的,所以就可以在寻找target的过程中每一次都判断是否是最接近的。

优化的细节是在双指针前加入当前这一轮,也就是first固定下来后的最大值和最小值与target的关系。如果最大的数都小于等于target,那直接下一轮,first往右也许能更大;如果最小的数都大于等于target,那压根别找了,因为不可能再有更小的数了,直接Break掉返回结果即可。

实现1

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        n = len(nums)
        nums.sort()         # 排序
        ans = float('inf')  # 无穷大

        for first in range(n-2):        # 枚举第一个元素
            if first > 0 and nums[first] == nums[first-1]: 
                continue     # 保证first不会有重复

            second, third = first + 1, n - 1
            max_sum = nums[first] + nums[-2] + nums[-1]
            min_sum = nums[first] + nums[first + 1] + nums[first + 2]
            if max_sum <= target:    # 最大的数
                if abs(max_sum - target) < abs(ans - target): # 当前差距和最小差距的比较
                    ans = max_sum
                continue              
            elif min_sum >= target:  # 最小的数
                if abs(min_sum - target) < abs(ans - target):
                    ans = min_sum      
                break   
                      
            while second < third:
                two_sum_target = target - nums[first]
                s = nums[second] + nums[third]
                if abs(s + nums[first] - target) < abs(ans - target):
                    ans = s + nums[first]
                if s > two_sum_target:  # 当前数值太大 右指针左移
                    third -= 1
                    while third > second and nums[third] == nums[third + 1]:
                        third -= 1
                elif s < two_sum_target:  # 当前数值太小 左指针右移
                    second += 1
                    while third > second and nums[second] == nums[second - 1]:
                        second += 1 
                else:                   # 刚好等于 直接返回target即可
                    return target 

        return ans

题目2

  • 题号:20
  • 难度:简单
  • https://leetcode-cn.com/problems/valid-parentheses/

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

示例 1:

输入: "()"
输出: true

示例 2:

输入: "()[]{}"
输出: true

示例 3:

输入: "(]"
输出: false

示例 4:

输入: "([)]"
输出: false

示例 5:

输入: "{[]}"
输出: true

示例 6:

输入: ""
输出: true

示例 7:

输入: "(("
输出: false

思路1

先出现的左括号后匹配,在python中列表可以当作栈!然后使用.pop()来弹出最后一个元素,.append()是加入元素。

实现1

class Solution:
    def isValid(self, s: str) -> bool:
        if len(s)%2==1:  # 长度是奇数的话不用判断
            return False
        dic = {')':'(',']':'[','}':'{'}  
        stack = []
        for i in s:
            if stack and i in dic: # 匹配到右括号并且栈中有元素
                if stack[-1] == dic[i]: # 栈的最后一个元素就是对应左括号
                    stack.pop() # 弹出
                else: 
                    return False
            else: 
                stack.append(i) # 将先出现的左括号加入
            
        return not stack

时间复杂度O(n) 只遍历了一遍字符串

题目3

  • 题号:21
  • 难度:简单
  • https://leetcode-cn.com/problems/merge-two-sorted-lists/

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

思路1

递归实现

合并的时候比较大小即可

实现1

class Solution:
    def mergeTwoLists(self, l1, l2):
        if l1 is None:
            return l2
        elif l2 is None:
            return l1
        elif l1.val < l2.val:
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1
        else:
            l2.next = self.mergeTwoLists(l1, l2.next)
            return l2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值