一、 手撕快速排序
快速排序的基本步骤: 选取数组中的一个元素作为基准元素(通常是数组的第一个元素)。 将数组中比基准元素小的元素移动到数组的左边,将比基准元素大的元素移动到数组的右边。
对左右两边的数组分别重复上述操作,直到所有数组都有序为止。 选择数组第一位元素位基准值,创建两个新数组,分别存放小于基准值和大于基准值的元素
然后这两个新数组递归进行上述操作(再选新数组,再分组),直到数组为空 然后将左右数组和基准值进行拼接
- 应用例子
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)
- 选择基准元素:从待排序数组中选择一个元素作为基准(通常选择第一个元素)
- 分割数组:重新排列数组,将所有小于基准的元素放在基准的左边,所有大于基准的元素放在基准的右边,等于基准的元素可以放在任意一边。此时,基准元素的位置也已经确定
- 递归排序: 递归地对基准元素左边的子数组和右边的子数组进行快速排序
- 合并结果:将左边子数组、基准元素、右边子数组依次拼接起来,得到排好序的数组
二、 合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
输入: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