链表专题系列

一、 手撕快速排序

快速排序的基本步骤: 选取数组中的一个元素作为基准元素(通常是数组的第一个元素)。 将数组中比基准元素小的元素移动到数组的左边,将比基准元素大的元素移动到数组的右边。
对左右两边的数组分别重复上述操作,直到所有数组都有序为止。 选择数组第一位元素位基准值,创建两个新数组,分别存放小于基准值和大于基准值的元素
然后这两个新数组递归进行上述操作(再选新数组,再分组),直到数组为空 然后将左右数组和基准值进行拼接

  • 应用例子
def quicksort(arr):
    # 如果数组长度小于等于1,则直接返回该数组
    if len(arr) <= 1:
        return arr
    else:
        # 选择第一个元素作为基准
        pivot = arr[0]
        # 构造小于等于基准的元素构成的子数组 less  构造大于基准的元素构成的子数组 greater
        less = [x for x in arr[1:] if x <= pivot]      # 输出比第一个元素小的列表
        greater = [x for x in arr[1:] if x > pivot]    # 输出比第一个元素大的列表
        print('less-----------', less)
        print('greater-----------', greater)
        # 递归地对这两个子数组进行快速排序,然后将它们合并起来,并加上基准元素
        return quicksort(less) + [pivot] + quicksort(greater)
        
if __name__ == '__main__':
    arr = [3, 5, 2, 8, 1, 4]
    sorted_arr = quicksort(arr)
    print(sorted_arr)
  1. 选择基准元素:从待排序数组中选择一个元素作为基准(通常选择第一个元素)
  2. 分割数组:重新排列数组,将所有小于基准的元素放在基准的左边,所有大于基准的元素放在基准的右边,等于基准的元素可以放在任意一边。此时,基准元素的位置也已经确定
  3. 递归排序: 递归地对基准元素左边的子数组和右边的子数组进行快速排序
  4. 合并结果:将左边子数组、基准元素、右边子数组依次拼接起来,得到排好序的数组

二、 合并两个有序链表

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

在这里插入图片描述

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:

输入:l1 = [], l2 = []
输出:[]
示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

提示:

两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序 排列

# 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:
            return list2

        if not list2:
            return list1
        
        if list1.val <= list2.val:
            list1.next = self.mergeTwoLists(list1.next, list2)
            return list1
        else:
            list2.next = self.mergeTwoLists(list1, list2.next)
            return list2
# 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]:
        head=ListNode(0)
        # 创建一个指针用于遍历合并链表
        current=head
        # 当两个链表同时都有节点时
        while list1 and list2:
            # 如果链表l1节点的值>=l2节点的值,将l2当前节点赋予current的下一个节点
            # 将l2指向其下一个节点
            if list1.val>=list2.val:
                current.next=list2
                list2=list2.next
            else:
                current.next=list1
                list1=list1.next
            current=current.next
        # 将剩余部分连接到合并链表的末尾
        current.next= list1 if list1 else list2

        return head.next

92. 反转链表 II

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例 1:
在这里插入图片描述
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
示例 2:

输入:head = [5], left = 1, right = 1
输出:[5]

提示:
链表中节点数目为 n
1 <= n <= 500
-500 <= Node.val <= 500
1 <= left <= right <= n

进阶: 你可以使用一趟扫描完成反转吗?

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]: 
        
        def rev(head):
            pre, cur = None, head
            while cur:
                next = cur.next
                cur.next = pre
                pre = cur
                cur = next
            return pre

        m=n = ListNode(0)
        n.next = head
        for _ in range(left - 1):
            n = n.next
        l = n
        mid = n.next
        for _ in range(right - left + 1):
            n = n.next

        r = n.next
        n.next = None

        l.next = rev(mid)
        mid.next = r

        return m.next

23. 合并 K 个升序链表

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例 2:
输入:lists = []
输出:[]

示例 3:
输入:lists = [[]]
输出:[]

提示:
k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i] 按 升序 排列
lists[i].length 的总和不超过 10^4

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
from queue import PriorityQueue
class Solution:
    def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
        nums = []
        
        for l in lists:
            while l:
                nums.append(l.val)
                l = l.next

        nums.sort()

        cur = head = ListNode(0)
        for i in nums:
            cur.next = ListNode(val=i)
            cur= cur.next

        return head.next

415. 字符串相加

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。

你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。

示例 1:
输入:num1 = “11”, num2 = “123”
输出:“134”

示例 2:
输入:num1 = “456”, num2 = “77”
输出:“533”

示例 3:
输入:num1 = “0”, num2 = “0”
输出:“0”

提示:
1 <= num1.length, num2.length <= 104
num1 和num2 都只包含数字 0-9
num1 和num2 都不包含任何前导零

class Solution:
    def addStrings(self, num1: str, num2: str) -> str:
        res = ""
        i,j,carry = len(num1)-1, len(num2)-1, 0

        while i>=0 or j >= 0:
            
            m = int(num1[i]) if i >= 0 else 0
            n = int(num2[j]) if j >= 0 else 0
            tmp = m + n + carry
            
            carry = tmp // 10
            res = str(tmp% 10) + res
            i,j = i-1, j-1

        return "1" + res if carry else res
  • 18
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值