2024.6.28刷题记录

目录

一、13. 罗马数字转整数

贪心

二、16. 最接近的三数之和

排序+指针

 三、17. 电话号码的字母组合

dfs(深度优先搜索)

四、19. 删除链表的倒数第 N 个结点

1.模拟

2.前后同步指针

五、20. 有效的括号

六、21. 合并两个有序链表

1.递归

2.迭代


一、13. 罗马数字转整数

贪心

class Solution:
    dict = {'I': 1, 'V': 5,
    'X': 10, 'L': 50,
    'C': 100, 'D': 500,
    'M': 1000}

    def romanToInt(self, s: str) -> int:
        # 贪心,若前面小于后面就相减
        n = len(s)
        ans = 0
        for i in range(n):
            if i == n - 1 or Solution.dict[s[i]] >= Solution.dict[s[i + 1]]:
                ans += Solution.dict[s[i]]
            else:
                ans -= Solution.dict[s[i]]
        return ans

二、16. 最接近的三数之和

排序+指针

又重新写了一遍这道题

class Solution:
    def threeSumClosest(self, nums: List[int], target: int):
        # 排序+ 指针
        nums.sort()
        if sum(nums[-3:]) <= target:
            return sum(nums[-3:])
        if sum(nums[:3]) >= target:
            return sum(nums[:3])

        ans1, ans2 = -math.inf, math.inf    # 左右区域
        n = len(nums)
        for i in range(n - 2):
            x = nums[i]
            if x + nums[-2] + nums[-1] <= ans1 or \
            x + nums[i + 1] + nums[i + 2] >= ans2:
                # 剪枝
                # 最大值小于等于左端点
                # 最小值大于等于右端点
                continue
            j, k = i + 1, n - 1
            while j < k:
                cur = x + nums[j] + nums[k]
                if cur == target:
                    return target
                elif cur > target:
                    ans2 = min(ans2, cur)
                    k -= 1
                else:
                    ans1 = max(ans1, cur)
                    j += 1
        return ans1 if target - ans1 < ans2 - target else ans2

 三、17. 电话号码的字母组合

dfs(深度优先搜索)

来自灵神题解(. - 力扣(LeetCode)),完全没想到。

MAPPING = "", "", "abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"
# 元组

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        # dfs
        if not digits:
            return []

        n = len(digits)
        ans = []
        path = ['' for _ in range(n)]   # path长度固定为n

        def dfs(i: int) -> None:
            nonlocal n
            if i == n:
                # 搜索到末尾
                ans.append(''.join(path))
                return
            for c in MAPPING[int(digits[i])]:
                path[i] = c # 覆盖
                dfs(i + 1)

        dfs(0)
        return ans

四、19. 删除链表的倒数第 N 个结点

1.模拟

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        # 模拟
        # 先求长度
        l = 0
        cur = head
        while cur:
            l += 1
            cur = cur.next

        dummy = ListNode(next = head)   # 哨兵节点
        l -= n  # 指到指定节点的前一个节点
        cur = dummy
        while l > 0:
            cur = cur.next
            l -= 1
        cur.next = cur.next.next    # 更改连接
        return dummy.next

2.前后同步指针

来自灵神题解(. - 力扣(LeetCode))。很妙!

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        # 前后同步指针
        left = right = dummy = ListNode(next = head)
        for _ in range(n):
            # 右指针先走n位
            right = right.next
        while right.next:
            # 走到指定节点的前一个节点,这里是right.next
            left = left.next
            right = right.next
        left.next = left.next.next
        return dummy.next

五、20. 有效的括号

class Solution:
    def isValid(self, s: str) -> bool:
        # 栈
        st = []
        hash = {')': '(', '}': '{', ']': '['}
        for c in s:
            if c in hash:
                # 右括号
                if not st or hash[c] != st[-1]:
                    return False
                st.pop()
            else:
                # 左括号
                st.append(c)
        return not st   # 为空即对

六、21. 合并两个有序链表

1.递归

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        # 递归
        if not list1 or not list2:
            return list1 if list1 else list2
        
        if list1.val < list2.val:
            list1.next = self.mergeTwoLists(list1.next, list2)
            return list1
        else:
            list2.next = self.mergeTwoLists(list1, list2.next)
            return list2

2.迭代

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        # 迭代
        dummy = ListNode()
        cur = dummy
        while list1 and list2:
            if list1.val <= list2.val:
                cur.next = list1
                cur = cur.next
                list1 = list1.next
            else:
                cur.next = list2
                cur = cur.next
                list2 = list2.next
        cur.next = list1 if list1 else list2
        return dummy.next

感谢你看到这里!一起加油吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值