枚举思想——算法学习(一)
前言
在算法学习的道路上,枚举思想是一种简单却强大的思想。作为一种暴力求解方法,枚举算法通过穷尽所有可能的解,从中找到满足条件的最优解或所有解。虽然它看似“低效”,但在解决许多实际问题时却显得直观且有效,尤其是在问题规模可控的情况下。
(本文代码均使用C#语言)
概念
枚举是一种通过穷举所有可能的情况来解决问题的算法思想。它的核心在于全面性和简单性:即按照某种规则,逐一列举出问题的所有可能解,然后通过判断筛选出符合条件的解。
枚举的特点
-
直观易懂
枚举算法通常不需要复杂的数学推导或高级技巧,直接通过遍历所有可能情况即可解决问题,因此非常适合初学者理解和使用。 -
适用范围广
枚举可以用于许多场景,例如搜索所有排列、组合、子集,验证某种结构或解决约束满足问题(CSP)。 -
时间复杂度高
由于需要遍历所有可能的解,枚举的时间复杂度通常较高,容易随着问题规模的增加而变得不可接受,因此一般用于规模较小的问题。
枚举算法的核心步骤
-
定义解空间
明确所有可能的解构成的范围。解空间可以是一个排列、一组数字的组合,甚至是一个几何图形。 -
遍历解空间
通过循环或递归的方式,逐一生成所有可能的解。 -
判断筛选
对每个可能的解进行判断,筛选出符合问题条件的解。
解空间
解空间是所有可能解构成的集合,等于其相关变量值域的笛卡尔积
最大/最小值问题
枚举法是列举解空间中的所有元素,以找到问题的合法解或最优解
问题形式一般为:给定一组数字,输出其中最大/最小的数字
例题
例:
解答
本题使用枚举思想求解,首先定义一个最大值max,然后将max置为最小,然后枚举所有数据与max进行比较,若大于max则将max更新为此数,若小于max则比较下一个。
代码
using System;class Test
{static void Main(string[] args) {var input = Console.ReadLine();var n =int.Parse(input);input = Console.ReadLine();string[] inputs=input.Split(' ');//将输入的字符串按空格分隔保存为数组int[] a= new int[n];for(int i = 0; i < n; i++) {a[i]=int.Parse(inputs[i]);}int max=int.MinValue;for(int i = 0; i < n; ++i) {if (a[i]>max)max = a[i];}Console.Write(max);}}
分析
- 解空间:对于最大值问题,解空间为数组元素的下标组成的集合{ 1 , 2 , ... , n },是一个1维的解空间
- 时间复杂度:O( n )