1. 排序链表
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def sortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
思路
使用归并排序, 因为归并排序的时间复杂度才是O(nlogn)
快排最好的时候是O(nlogn), 最差的时候是O(n^2)
归并排序示意图:
https://pic.leetcode-cn.com/8c47e58b6247676f3ef14e617a4686bc258cc573e36fcf67c1b0712fa7ed1699-Picture2.png
总的思路:分割、递归、合并
"""
if not head or not head.next: # 无节点或者单节点, 递归终止
return head
# 分割
slow, fast = head, head.next # 设置快慢指针找到分割点
while slow and fast and fast.next:
slow = slow.next
fast = fast.next.next
left, right = head, slow.next # 设置左右链表指针
slow.next = None # 链表分割
# 递归
left, right = self.sortList(left), self.sortList(right)
# 合并
head = ListNode(0) # 空的头节点
tmp = head
while left and right:
if left.val < right.val: # 当前left节点小, 连接到head
tmp.next, left = left, left.next
else: # 当前right节点小, 连接到head
tmp.next, right = right, right.next
tmp = tmp.next
if left or right: # left或right还有节点剩余, 连接到head
tmp.next = left if left else right
return head.next
2. 数组中的第K个最大元素
215. kth-largest-element-in-an-array
class Solution(object):
def findKthLargest(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
笨办法
nums.sort(); return nums[-k]
聪明解法
维护一个最大size为k的小顶堆, 将nums所有元素一个一个加进去, 堆满则弹出
最终返回堆顶元素
heapq.nlargest(k, nums)[-1]
"""
import heapq
return heapq.nlargest(k, nums)[-1]
3. 前 K 个高频元素
class Solution(object):
def topKFrequent(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
思路
用字典统计并存储num及频数, 然后按频数排序返回
python内置的sort函数使用timsort方法实现, 它是在归并排序基础上的优化, 时间复杂度在O(n)~O(nlogn)
拿到频数后, 或者不用sort函数, 用一个大小为k的大顶堆来存储, 取所有元素即为所求结果
"""
dic = {}
for num in nums:
if num not in dic:
dic[num] = 0
dic[num] += 1
result = [
num for num, freq in sorted(dic.items(), key=lambda t: t[1], reverse=True)[:k]
]
return result