在算法面试和实际工程中,快速查找数组中的特定顺序元素是高频出现的经典问题。题目215要求找出未排序数组中第K个最大的元素,而题目912则需要实现完整的数组排序。这两个问题看似独立,实则存在深刻的内在联系——它们本质上都是对数组元素的顺序处理问题。
从实际应用角度看,这类算法在以下场景中至关重要:
最直观的解法是直接调用语言内置排序:
python复制def findKthLargest(nums, k):
nums.sort()
return nums[-k]
时间复杂度为O(nlogn),空间复杂度取决于排序实现(通常为O(1)或O(n))。虽然简单,但在面试中往往不是最优解。
更高效的解法是使用堆结构:
python复制import heapq
def findKthLargest(nums, k):
heap = []
for num in nums:
heapq.heappush(heap, num)
if len(heap) > k:
heapq.heappop(heap)
return heap[0]
建立大小为k的小顶堆,时间复杂度O(nlogk),空间复杂度O(k)。当k远小于n时优势明显。
结合快速排序思想的改进算法:
python复制def findKthLargest(nums, k):
def quickselect(left, right, k_smallest):
pivot = partition(left, right)
if pivot == k_smallest:
return nums[pivot]
elif pivot < k_smallest:
return quickselect(pivot + 1, right, k_smallest)
else:
return quickselect(left, pivot - 1, k_smallest)
def partition(left, right):
pivot = nums[right]
i = left
for j in range(left, right):
if nums[j] < pivot:
nums[i], nums[j] = nums[j], nums[i]
i += 1
nums[i], nums[right] = nums[right], nums[i]
return i
return quickselect(0, len(nums)-1, len(nums)-k)
平均时间复杂度O(n),最坏情况O(n²),空间复杂度O(1)。实际工程中常采用随机化pivot来避免最坏情况。
python复制def sortArray(nums):
def quicksort(left, right):
if left >= right:
return
pivot = partition(left, right)
quicksort(left, pivot-1)
quicksort(pivot+1, right)
def partition(left, right):
pivot = nums[right]
i = left
for j in range(left, right):
if nums[j] < pivot:
nums[i], nums[j] = nums[j], nums[i]
i += 1
nums[i], nums[right] = nums[right], nums[i]
return i
quicksort(0, len(nums)-1)
return nums
python复制def sortArray(nums):
def merge_sort(l, r):
if l >= r:
return
mid = (l + r) // 2
merge_sort(l, mid)
merge_sort(mid+1, r)
merge(l, mid, r)
def merge(l, mid, r):
temp = []
i, j = l, mid+1
while i <= mid and j <= r:
if nums[i] <= nums[j]:
temp.append(nums[i])
i += 1
else:
temp.append(nums[j])
j += 1
temp.extend(nums[i:mid+1])
temp.extend(nums[j:r+1])
nums[l:r+1] = temp
merge_sort(0, len(nums)-1)
return nums
实际项目中常根据数据特征选择不同算法:
现代CPU缓存机制下,访问局部性对性能影响显著:
对于超大规模数据:
常见陷阱包括:
需要保持元素相对顺序时:
实际测试中的优化方向:
当数据以流形式到达时:
海量数据下的解决方案:
元素带有权重时的扩展: