个人刷题与算法实现过程记录,保留可运行的源码片段。
最简单的排序算法,相邻两个数比较交换,每轮把最大的数"冒"到最后。
def bubble_sort(arr):
n = len(arr)
for i in range(n - 1):
for j in range(n - 1 - i):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
print(bubble_sort([5, 2, 9, 1, 5, 6])) # [1, 2, 5, 5, 6, 9]
二分查找要求数组有序。练习时最容易出错的是 left <= right 还是 left < right,以及 mid 是否要加减一。
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
print(binary_search([1, 3, 5, 7, 9], 7)) # 3
递归写法简单但有重复计算,练习时改成递推(自底向上)效率更高。
def fib(n):
if n < 2:
return n
a, b = 0, 1
for _ in range(n - 1):
a, b = b, a + b
return b
print([fib(i) for i in range(10)]) # [0,1,1,2,3,5,8,13,21,34]
经典入门题。暴力双重循环是 O(n²),用哈希表可以降到 O(n)。
def two_sum(nums, target):
seen = {}
for i, num in enumerate(nums):
if target - num in seen:
return [seen[target - num], i]
seen[num] = i
return []
print(two_sum([2, 7, 11, 15], 9)) # [0, 1]
Python 里用切片反转字符串最简洁,也可以练习用双指针实现。
# 切片写法
print("hello"[::-1]) # olleh
# 双指针写法
def reverse(s):
chars = list(s)
i, j = 0, len(chars) - 1
while i < j:
chars[i], chars[j] = chars[j], chars[i]
i += 1
j -= 1
return "".join(chars)
print(reverse("code")) # edoc