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