复习算法
二分查找
#python
def binary_search(arr,target):
left = 0 #左指针
right = len(arr)-1 #右指针
while left <= right: #主体循环,循环前提:左指针要小于右指针
mid = (left+right)//2 #找到中间指针位置
if arr[mid] == target: #如果中间指针正好为目标,则中间指针就为目标索引(条件1)
return mid
elif arr[mid] < target: #目标值在中指针右侧情况 (条件2)
left = mid + 1
else: #在左侧情况,即arr[mid] > target (条件3)
right = mid - 1
return -1 #三种情况都不满足则为查找失败,返回-1
#测试用例
数列必须有序必须有序!,如果为无序数列先试用sorted方法排序!!!
test_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
print(binary_search(test_array, 10))
快速排序
def quick_sort(arr):
"""
快速排序算法实现
原理:采用分治法思想,选择一个基准元素,将数组分为两部分,
一部分所有元素小于基准,另一部分所有元素大于等于基准,
然后递归对两部分进行排序
参数:
arr: 待排序的列表
返回:
排序后的列表
"""
# 基本情况:如果列表长度小于等于1,则已经是有序的,直接返回
if len(arr) <= 1:
return arr
# 选择基准元素(pivot),这里选择列表的第一个元素
pivot = arr[0]
# 分割过程:将小于基准的元素放入left列表,大于等于基准的放入right列表
left = [] # 存储小于基准的元素
right = [] # 存储大于等于基准的元素
# 遍历列表中除基准外的所有元素
for element in arr[1:]:
if element < pivot:
left.append(element)
else:
right.append(element)
# 递归排序左右两部分,并将结果与基准元素合并
# 排序左半部分 + [基准元素] + 排序右半部分
return quick_sort(left) + [pivot] + quick_sort(right)
冒泡排序
# python
def bubble_sort(arr):
n = len(arr)
# 遍历所有数组元素
for i in range(n):
# 最后一轮可以少比较一次,因为最大的元素已经排好位置
for j in range(0, n - i - 1):
# 如果当前元素大于后一个元素,则交换
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
字符串反转
# 方法1:使用切片(最简洁高效)
def reverse_str_slice(s):
"""通过切片操作实现字符串反转
切片语法:s[start:end:step],step为-1表示反向取值"""
return s[::-1]
# 方法2:使用循环遍历
def reverse_str_loop(s):
"""通过循环从后往前拼接字符实现反转"""
reversed_str = ""
# 从最后一个索引遍历到第一个索引(包含)
for i in range(len(s)-1, -1, -1):
reversed_str += s[i]
return reversed_str
# 方法3:使用reversed()函数
def reverse_str_reversed(s):
"""利用内置reversed()函数,返回反转的迭代器,再拼接为字符串"""
# reversed()返回迭代器,需用join()转换为字符串
return ''.join(reversed(s))
字符串去重:
#保持原有顺序(推荐)
def remove_duplicates_keep_order(s):
"""
移除字符串中重复的字符,保留第一次出现的顺序
原理:用列表记录已出现的字符,遍历字符串时只保留未出现过的字符
"""
seen = [] # 记录已出现的字符
result = [] # 存储去重后的结果
for char in s:
if char not in seen:
seen.append(char)
result.append(char)
return ''.join(result) # 拼接列表为字符串
判断字符串是否为回文串:
def is_palindrome(s):
"""
判断字符串是否为回文串(不使用正则表达式)
步骤:
1. 手动过滤非字母数字字符(仅保留a-z、A-Z、0-9)
2. 转换为小写统一大小写
3. 比较处理后的字符串与反转字符串是否相等
参数:
s: 待判断的字符串
返回:
bool: 是回文串返回True,否则返回False
"""
# 1. 过滤非字母数字字符
filtered = []
for char in s:
# isalnum() 方法判断字符是否为字母或数字
if char.isalnum():
filtered.append(char)
# 转换为字符串并统一为小写
cleaned = ''.join(filtered).lower()
# 3. 判断是否与反转后相同
return cleaned == cleaned[::-1]
两个列表,打印两个数组不重合部分
# 方法1:获取不重合的元素(去重,只关注元素是否存在)
def get_non_overlapping_unique(list1, list2):
"""
找出两个列表中不重合的元素(去重)
逻辑:只在list1中存在 或 只在list2中存在的元素(不考虑出现次数)
"""
set1 = set(list1)
set2 = set(list2)
# 只在list1中的元素 + 只在list2中的元素
return list(set1 - set2) + list(set2 - set1)
列表去重:
def deduplicate_no_order(lst):
"""
利用集合的唯一性去重,会打乱原有顺序
特点:代码简洁,执行效率高(时间复杂度O(n))
"""
return list(set(lst))
# 方法2:保持原有顺序(Python 3.7+,推荐)
def deduplicate_keep_order(lst):
"""
利用字典键的唯一性去重,同时保留元素首次出现的顺序(Python 3.7+字典有序)
特点:兼顾顺序和效率(时间复杂度O(n))
"""
# dict.fromkeys(lst) 会按顺序保留唯一键,再转换为列表
return list(dict.fromkeys(lst))
# 方法3:保持原有顺序(兼容低版本Python)
def deduplicate_keep_order_compatible(lst):
"""
手动遍历列表,记录已出现元素,保留首次出现顺序(兼容Python 3.6及以下)
特点:兼容性好,但效率略低(时间复杂度O(n²))
"""
seen = [] # 记录已出现的元素
result = []
for item in lst:
if item not in seen:
seen.append(item)
result.append(item)
return result
二分排序:
# python
def binary_sort(arr):
"""
使用二分插入排序算法对列表进行排序
参数:
arr: 需要排序的列表
返回:
排序后的列表
"""
# 遍历列表,从第二个元素开始
for i in range(1, len(arr)):
key = arr[i]
# 使用二分查找找到插入位置
left, right = 0, i
while left < right:
mid = (left + right) // 2
if arr[mid] < key:
left = mid + 1
else:
right = mid
# 将元素插入到正确位置
# 从i-1到left的元素依次后移一位
for j in range(i, left, -1):
arr[j] = arr[j-1]
arr[left] = key
return arr