(1) 21. 合并两个有序链表(易)
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
思路: 遍历两个链表,谁小要谁
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if not l1 and not l2:
return
dumy = new = ListNode(0) #注意要一个虚拟结点
while l1 and l2:
if l1.val<l2.val:
new.next=l1
l1=l1.next
else:
new.next=l2
l2=l2.next
new = new.next
if not l1: #接上后面的
new.next=l2
if not l2:
new.next=l1
return dumy.next
(2) 23. 合并K个排序链表(难)
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
思路: 遍历每一个链表,把每个节点的value压入最小堆。然后从最小堆循环pop出value重新构建新链表。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
import heapq
hpq = list()
for l in lists:
while l:
heapq.heappush(hpq, l.val)
l = l.next
head = new = ListNode()
while hpq:
new.next = ListNode(heapq.heappop(hpq))
new = new.next
return head.next
(3) 88. 合并两个有序数组(易)
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n。
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
思路:
方法一:常规双指针,类似题(1)
方法二:倒序双指针,把最大的放入nums1末尾,因为最后需要返回的是nums1。
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
i = m-1
j = n-1
res = m + n - 1
while res >= 0:
if i >= 0 and j >= 0:
if nums1[i] >= nums2[j]:
nums1[res] = nums1[i]
i -= 1
else:
nums1[res] = nums2[j]
j -= 1
elif j >= 0:
nums1[res] = nums2[j]
j -= 1
res -= 1
(3) 378. 有序矩阵中第K小的元素(中)
给定一个 n x n 矩阵,其中每行和每列元素均按升序排序(相邻元素可能相等),找到矩阵中第k小的元素。
请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素。
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
返回 13。
思路: 大根堆(负数小根堆)保持堆中含有k个数。
class Solution:
def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
n = len(matrix)
hpq = list()
for i in range(n):
for j in range(n):
if len(hpq) < k:
heapq.heappush(hpq, -matrix[i][j])
elif -hpq[0] > matrix[i][j]:
heapq.heappop(hpq)
heapq.heappush(hpq, -matrix[i][j])
return -hpq[0]
(4) 632. 最小区间(难)
你有 k 个升序排列的整数数组。找到一个最小区间,使得 k 个列表中的每个列表至少有一个数包含在其中。
我们定义如果 b-a < d-c 或者在 b-a == d-c 时 a < c,则区间 [a,b] 比 [c,d] 小。
输入:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
输出: [20,24]
解释:
列表 1:[4, 10, 15, 24, 26],24 在区间 [20,24] 中。
列表 2:[0, 9, 12, 20],20 在区间 [20,24] 中。
列表 3:[5, 18, 22, 30],22 在区间 [20,24] 中。
逃(w)
(5) 373. 查找和最小的K对数字(中)
给定两个以升序排列的整数数组 nums1 和 nums2 , 以及一个整数 k。
定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2。
请找到和最小的 k 个数对 (u1,v1), (u2,v2) … (uk,vk)。
输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3
输出: [1,2],[1,4],[1,6]
解释: 返回序列中的前 3 对数:
[1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
思路: 先把nums1中所有元素和nums2首元素的组合放进堆中(包括下标),然后下一轮把nums1中所有元素和nums2第二个元素的组合放进堆中,以此类推。一共进行k轮,每轮将堆顶元素加入结果数组。
class Solution:
def kSmallestPairs(self, nums1: List[int], nums2: List[int], k: int) -> List[List[int]]:
m, n = len(nums1), len(nums2)
ans = []
pq = [(nums1[i] + nums2[0], i, 0) for i in range(min(k, m))]
heapq.heapify(pq)
while pq and k:
_, i, j = heapq.heappop(pq)
ans.append([nums1[i], nums2[j]])
if j < len(nums2) - 1:
heapq.heappush(pq, (nums1[i] + nums2[j+1], i, j+1))
k -= 1
return ans
(6) 786. 第 K 个最小的素数分数(难)
素数一般指质数,质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
给你一个按递增顺序排序的数组 arr 和一个整数 k 。数组 arr 由 1 和若干 素数 组成,且其中所有整数互不相同。
对于每对满足 0 <= i < j < arr.length 的 i 和 j ,可以得到分数 a r r [ i ] / a r r [ j ] arr[i] / arr[j] arr[i]/arr[j]。
那么第 k 个最小的分数是多少呢? 以长度为 2 的整数数组返回你的答案, 这里 a n s w e r [ 0 ] = = a r r [ i ] answer[0] == arr[i] answer[0]==arr[i] 且 a n s w e r [ 1 ] = = a r r [ j ] answer[1] == arr[j] answer[1]==arr[j] 。
输入:arr = [1,2,3,5], k = 3
输出:[2,5]
解释:已构造好的分数,排序后如下所示:
1/5, 1/3, 2/5, 1/2, 3/5, 2/3
很明显第三个最小的分数是 2/5
思路: 和(5)一样。最后返回的是结果数组的最后一个元素。
class Solution:
def kthSmallestPrimeFraction(self, arr: List[int], k: int) -> List[int]:
m = len(arr)
rev = arr[::-1]
pq = [(arr[i]/rev[0], i, 0) for i in range(m)]
res = list()
heapq.heapify(pq)
while k:
_, i, j = heapq.heappop(pq)
res.append([arr[i], rev[j]])
if j < m - 1:
heapq.heappush(pq, (arr[i]/rev[j+1], i, j+1))
k -= 1
return res[-1]