以下是顺序查找(Linear Search)和二分查找(Binary Search)算法的解释:
顺序查找(Linear Search)
基本思想:
顺序查找也称为线性查找,是最简单的查找算法。它的基本思想是从表的一端开始,顺序扫描线性表,逐个地检查记录中的关键字是否满足给定的条件。若表中存在一个和关键字相等的记录,则查找成功;若表中不存在和关键字相等的记录,则查找失败。
算法步骤:
- 从列表的第一个元素开始,检查当前元素是否为目标元素。
- 如果不是,则移动到下一个元素。
- 重复步骤1和2,直到找到目标元素或检查完列表中的所有元素。
时间复杂度:
- 平均时间复杂度:O(n),其中n是列表的长度。因为最坏情况下需要检查列表中的所有元素。
- 最好时间复杂度:O(1),如果目标元素恰好在列表的第一个位置。
空间复杂度:
- O(1),因为顺序查找只需要常数级别的额外空间来存储变量。
二分查找(Binary Search)
基本思想:
二分查找也称为折半查找,是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。
前提条件:
- 数组必须是有序的。
算法步骤:
- 初始化两个指针left和right,分别指向数组的第一个元素和最后一个元素。
- 计算中间元素mid的索引:(left + right) // 2。
- 检查中间元素是否为目标元素。如果是,返回mid;如果不是,则根据目标元素与中间元素的大小关系,更新left或right的指针。
- 重复步骤2和3,直到找到目标元素或left > right(表示列表中没有目标元素)。
时间复杂度:
- 平均时间复杂度:O(log n),其中n是数组的长度。因为每次查找都会将搜索空间减半。
- 最好和最坏时间复杂度:O(1),如果目标元素恰好在数组的中间位置,或者数组为空。
空间复杂度:
- O(1),因为二分查找只需要常数级别的额外空间来存储变量。
贪心算法(Greedy Algorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。贪心算法并不总是能得到全局最优解,但对许多问题它能产生较好的近似解。贪心算法的关键在于贪心策略的选择,它必须是无后效性的,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。
贪心算法的特点:
- 每一步选择都是当前最优的:贪心算法在每一步都做出当前状态下的最优选择,即局部最优解。
- 不一定能得到全局最优解:由于贪心算法只考虑当前状态的最优解,而不考虑全局最优解,因此有时无法得到全局最优解。
- 时间复杂度较低:由于贪心算法在每一步都做出选择,因此其时间复杂度通常较低。
例子:找零钱问题
假设有1元、2元、5元、10元四种面额的纸币,现在要用这些纸币来凑出n元(n为正整数)。问最少需要多少张纸币?
贪心策略:
- 尽可能多地使用面额大的纸币。
- 如果当前面额的纸币无法凑出剩余金额,则选择面额次一级的纸币,以此类推。
伪代码:
输入:n(需要凑出的金额) | |
输出:所需纸币的最少张数 | |
初始化纸币面额数组 coins = [10, 5, 2, 1] // 按照面额从大到小排序 | |
初始化所需纸币张数 count = 0 | |
对于每一个面额 coin in coins: | |
while (n >= coin): // 当剩余金额大于等于当前面额时 | |
n = n - coin // 使用一张当前面额的纸币 | |
count = count + 1 // 纸币张数加一 | |
返回 count |
示例:
如果 n = 11,那么根据贪心策略:
- 先用10元的纸币,用1张(n=11-10=1)。
- 再用1元的纸币,用1张(n=1-1=0)。
总共需要2张纸币。这就是贪心算法在这个问题上的应用。