递归
递归是一种解决问题的方法,它将问题分解成更小的子问题来解决。在函数内部,它调用自身以解决这些子问题。
基本思想
-
函数自身调用:递归函数在解决问题时会直接或间接地调用自身。
-
基本情况:递归函数必须有一个或多个基本情况,它们会在递归过程中终止。
示例
def factorial(n):
# 基本情况
if n == 0:
return 1
# 递归调用
else:
return n * factorial(n - 1)
注意事项
-
递归需要合适的基本情况来终止递归过程,否则会陷入无限循环。
-
递归可能会因为递归层级过深导致栈溢出。在Python中,可以通过设置递归的最大深度来解决这个问题。(sys模块的sys.setrecursionlimit)
-
递归可能会比迭代慢,因为它涉及到函数调用的开销。
-
递归在某些问题中可能会很有用,但并非所有问题都适合使用递归解决。
-
谨慎使用递归,确保理解递归调用的逻辑和终止条件。
算法基础
算法简介
算法是一组有序的步骤或规则,用于解决特定问题或执行特定任务的有限计算过程。它们在计算机科学和数学领域中起着至关重要的作用,用于解决各种问题,从简单的数学运算到复杂的数据处理和优化任务。
基本特点
-
有限性: 算法必须在有限的步骤内结束,不能无限循环或无限执行。
-
明确性: 算法的每一步都必须明确定义,没有歧义。
-
输入和输出: 算法需要接受输入数据,并生成输出结果。
-
有效性: 算法必须在合理的时间内执行完成,不能花费过多时间。
-
通用性: 算法是一种通用解决方案,可以解决多个实例或问题。
-
可行性: 算法需要使用已知的计算机资源和内存。
-
优化: 算法的设计目标之一是尽可能高效,以节省时间和资源。
算法类别
-
排序算法: 用于按照一定规则对数据进行排序,如快速排序、归并排序、冒泡排序等。
-
搜索算法: 用于在数据集合中查找特定元素或信息,如二分查找、线性搜索、深度优先搜索、广度优先搜索等。
-
图算法: 用于解决图结构相关的问题,如最短路径、最小生成树、拓扑排序等。
-
动态规划: 一种通过将问题分解为子问题并保存子问题的解来解决问题的方法,如背包问题、最长公共子序列问题等。
-
贪心算法: 一种通过每一步都选择当前最优解的方法,通常用于优化问题,如霍夫曼编码、最小生成树算法等。
-
分治算法: 一种将问题分成更小的子问题并递归解决的方法,如快速排序、归并排序等。
应用领域
算法的选择取决于问题的性质和要求,不同的问题可能需要不同的算法来达到最佳解决方案。算法设计和分析是计算机科学领域的重要研究方向之一,它们对于解决实际问题和提高计算机程序的性能至关重要。
二分查找(Binary Search)
二分查找是一种高效的搜索算法,适用于已排序的数据集合。它通过将目标值与数据集合中间的元素进行比较,从而将搜索范围缩小一半,直到找到目标值或确定目标值不存在为止。
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
这是一个用于在有序数组 arr 中查找目标值 target 的二分查找函数。
解释一下这段代码:
-
left 和 right 分别代表搜索范围的左边界和右边界,初始时分别设置为数组的起始和结束位置。
-
进入 while 循环,只要左边界不大于右边界,就会一直进行查找。
-
计算中间位置 mid,它是左边界和右边界的平均值。
-
检查中间元素 arr[mid] 与目标值 target 的关系:
-
如果它们相等,表示找到了目标值,返回中间位置 mid。
-
如果目标值小于中间元素,说明目标值可能在左半部分,因此更新右边界 right 为 mid - 1。
-
如果目标值大于中间元素,说明目标值可能在右半部分,因此更新左边界 left 为 mid + 1。
-
如果经过一系列比较后仍未找到目标值,说明它不存在于数组中,返回 -1。
l = [11, 2, 3, 43, 55, 67, 23, 45, 45, 88, 99, 66,]
# l = ['kevin', 'jerry', 'tank', 'abc']
# 1. 排序
l.sort()
# ['abc', 'jerry', 'kevin', 'tank']
# print(l) # [2, 3, 11, 23, 43, 45, 45, 55, 66, 67, 88, 99]
# 2. 去列表的中间那个值,然后给66比较
target_num = 200
def my_half(l,target_num):
if len(l) == 0:
print('没找到')
return
# 3. 取的就是中间的那个索引
middle_index = len(l) // 2 # 向下取整 5 // 2 == 2 6 // 2 == 3
if target_num > l[middle_index]:
l_right = l[middle_index+1:] #
print(l_right)
my_half(l_right, target_num)
elif target_num < l[middle_index]:
l_left = l[:middle_index]
print(l_left)
my_half(l_left, target_num)
else:
print('找到了')
my_half(l, target_num)
这段Python代码基于递归实现了一个基于二分查找的查找算法。
- 首先,给定了一个列表 l,并对其进行了排序,这确保了列表是有序的。
- 然后,定义了一个名为 my_half 的递归函数,接受两个参数 l 和 target_num。这个函数的作用是在列表 l 中查找目标值 target_num。
- 在函数内部:
- 如果列表 l 的长度为0,说明列表为空,意味着目标值不存在于列表中,打印"没找到"并返回。
- 计算了中间元素的索引 middle_index,它是列表长度整除2的结果,即取中间值的索引位置。
- 接着,比较目标值 target_num 与中间元素 l[middle_index] 的大小关系:
- 如果 target_num 大于中间元素,就将列表切片为右半部分,并递归 调用 my_half 函数,以在右半部分中继续查找。
- 如果 target_num 小于中间元素,就将列表切片为左半部分,并递归调用 my_half 函数,以在左半部分中继续查找。
- 如果 target_num 等于中间元素,说明目标值已经找到,打印"找到了"。如果目标值不存在于列表中,最终会打印"没找到"。
三元运算符
三元运算符是一种在Python中用于简洁地实现条件表达式的方法。它也被称为条件表达式,其基本语法如下:
x if condition else y
这个表达式的意思是:如果条件condition
为真,则返回x
;否则返回 y
。
以下是对三元运算符的解释:
condition
:一个布尔表达式,用于判断条件是否为真。
x
:当条件为真时,返回的值。
y
:当条件为假时,返回的值。
这种表达式的使用可以使得代码更加简洁和可读,特别是在需要根据条件选择不同的值时。
举例来说,假设我们需要根据一个变量is_even
判断一个数是否为偶数,然后返回相应的字符串。我们可以使用三元运算符来实现:
num = 6
is_even = True if num % 2 == 0 else False
result = "偶数" if is_even else "奇数"
在这个例子中,如果 num 是偶数,则 is_even 将为 True,因此 result 将被赋值为字符串 “偶数”。如果 num 是奇数,则 is_even 将为 False,因此 result 将被赋值为字符串 “奇数”。
总的来说,三元运算符是一种在特定情况下简化代码的有效方法,可以使得代码更加清晰和紧凑。
生成式(推导式)
1. 列表生成式
列表生成式是一种简洁的语法,允许你在一行代码中创建新的列表,通常是通过对现有列表进行变换或筛选。
[expression for item in iterable if condition]
这里的 expression
是对每个 item
执行的操作,item
是来自 iterable
的元素,condition
是一个可选的条件,只有当条件为 True
时才会将 item
加入新列表。
示例:筛选偶数
even_numbers = [x for x in range(1,101) if x % 2 == 0]
字典生成式
字典生成式(Dictionary Comprehension)是一种在一行代码中创建新字典的方法,类似于列表生成式。它允许你以简洁的方式通过对现有字典进行变换或筛选来创建新的字典。
{key_expression: value_expression for item in iterable if condition}
这里的 key_expression
和 value_expression
分别是对每个 item
执行的操作,tem
是来自 iterable
的元素,condition
是一个可选的条件,只有当条件为 True
时才会将 item
加入新字典。
示例:筛选出偶数并将其平方作为值
even_squares_dict = {x: x**2 for x in range(1,101) if x % 2 == 0}
集合生成式
集合生成式(Set Comprehension)是一种在一行代码中创建新集合的方法,类似于列表生成式和字典生成式。它允许你以简洁的方式通过对现有集合进行变换或筛选来创建新的集合。
{expression for item in iterable if condition}
这里的 expression
是对每个 item
执行的操作,item
是来自 iterable
的元素,condition
是一个可选的条件,只有当条件为 True
时才会将 item
加入新集合。
示例:筛选出偶数
even_numbers_set = {x for x in range(1,101) if x % 2 == 0}