線性排序(Linear sort),指的是時間複雜度為O(n)的排序演算法,之所以時間複雜度能達到線性,是因為這種排序非基於比較的,但它的適用場景也有很大的限制。
線性排序法有三種:
桶排序(Bucket Sort)、計數排序(Counting Sort)、基數排序(Radix Sort)。
排序算法 | 時間複雜度 | 空間複雜度 |
---|---|---|
桶排序 | O(n) | O(n) |
計數排序 | O(n) | O(n+k) |
基數排序 | O(k*n) | O(n) |
桶排序適用於數據範圍較集中且分佈均勻的情況,將數據分到若干個「桶」裡,然後對每個桶內的數據進行排序,最後將每個桶內的數據合併起來。
學習影片: https://www.youtube.com/watch?v=8uMEZ7aKICI
步驟:
def bucket_sort(arr):
# 創建桶
bucket_count = len(arr)
buckets = [[] for _ in range(bucket_count)]
# 將元素分配到相應的桶
for num in arr:
index = int(bucket_count * num) # 假設數據在[0,1)之間
buckets[index].append(num)
# 對每個桶進行排序
for bucket in buckets:
bucket.sort()
# 合併所有桶中的數據
sorted_arr = []
for bucket in buckets:
sorted_arr.extend(bucket)
return sorted_arr
計數排序是一種基於數字頻率的排序方法,適用於整數範圍較小的數據。它通過計算每個元素出現的次數來排序數列。
學習影片: https://www.youtube.com/watch?v=uHHKQBIfUOU
步驟:
def counting_sort(arr):
# 找到最大和最小值
max_val = max(arr)
min_val = min(arr)
# 初始化計數陣列
count_range = max_val - min_val + 1
count = [0] * count_range
# 計算每個元素的出現次數
for num in arr:
count[num - min_val] += 1
# 生成排序後的數列
sorted_arr = []
for i in range(count_range):
sorted_arr.extend([i + min_val] * count[i])
return sorted_arr
基數排序適用於處理數字(如整數或浮點數)和字符串的排序。它將數字的每一位(如個位、十位等)分別進行排序,從最低位到最高位逐步排序。
學習影片: https://www.youtube.com/watch?v=TYmQNCwRxeI
步驟:
def counting_sort_for_radix(arr, exp):
n = len(arr)
output = [0] * n
count = [0] * 10
# 計算每位數的出現次數
for i in range(n):
index = (arr[i] // exp) % 10
count[index] += 1
# 修改計數陣列,使其變成位置陣列
for i in range(1, 10):
count[i] += count[i - 1]
# 構建輸出數組
for i in range(n - 1, -1, -1):
index = (arr[i] // exp) % 10
output[count[index] - 1] = arr[i]
count[index] -= 1
# 將排序結果存回原數組
for i in range(n):
arr[i] = output[i]
def radix_sort(arr):
max_val = max(arr)
# 對每個數位進行計數排序
exp = 1
while max_val // exp > 0:
counting_sort_for_radix(arr, exp)
exp *= 10
題目描述:
給定一個數組 nums
,對於其中的每個元素 nums[i]
,計算有多少個數小於 nums[i]
。換言之,對於每一個 nums[i]
,都要數一下有多少個數小於它,返回答案數組。
這道題目是請ChatGPT出的,雖然通常用比較排序來解決,但可以用計數排序來實現,讓時間複雜度能達到𝑂(𝑛)。
class Solution(object):
def smallerNumbersThanCurrent(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
count = [0] * 101
for num in nums:
count[num] += 1
for i in range(1, 101):
count[i] += count[i - 1]
result = []
for num in nums:
if num == 0:
result.append(0)
else:
result.append(count[num - 1])
return result
程式步驟:
count
,因為數字範圍是 [0, 100]。nums
,增加相應數字在 count
中的位置。count
陣列中。