一、算法的重要性
1、适用人群
此系列会从 「算法」 零基础开始讲,目的当然是帮助想要涉足算法领域,或者正在找工作的朋友,以及将要找工作的大学生,更加有效快速的掌握算法思维,能够在职场面试和笔试中一展身手。
这篇文章中,我会着重讲解一些常见的 「算法」 的设计思想,并且配上动图。主要针对面试中常见的问题和新手朋友们比较难理解的点进行解析。
所以,无论你是 小学生,中学生,高中生,大学生,职场人士,只要想开始,一切都不会太晚!
2、有何作用
我们平常使用的 智能手机、搜索引擎、网站、操作系统、游戏、软件、人工智能,都大量地应用了 「算法」 的知识,以及平时你用到的各种库的底层实现,也是通过各种算法和数据结构组合出来的,所以可以说,有程序的地方,就有江湖算法。
现在一些主流的大厂,在面试快结束的时候都会 奉上一道算法题,如果你敲不出来,可能你的 offer 年包就打了 七折,或者直接与 offer 失之交臂。
所以,你问我算法和数据结构有什么用?我可以很明确的说,和你的年薪息息相关。
二、算法简介
算法是什么东西?
算法 + 数据结构 = 软件
算法是软件的灵魂,是计算机科学各个研究领域的核心
它是一种方法,一种解决问题的方案。
算法 | 是解决问题的方法或过程,严格地讲是满足下述性质的指令序列 |
---|---|
输入 | 有零个或多个外部量作为算法的输入 |
输出 | 算法产生至少一个量作为输出 |
确定性 | 组成算法的每条指令清晰、无歧义 |
有限性 | 算法中每条指令的执行次数有限,执行每条指令的时间也有限 |
程序 | 是算法用某种程序设计语言的具体实现。程序可以不满足算法的性质(4)即有限性 |
---|
三、算法初体验
在一个平面上有一个圆和n条直线,这些直线中每一条在圆内同其他直线相交,假设没有3条直线相交于一点,试问这些直线将圆分成多少区域。
假设F(n)为将圆分割成部分的函数,归纳如下:
F(1)=2
F(n)=F(n-1)+n
问题描述:给定一个整数数组{𝐴1,𝐴2, … ,𝐴𝑛},连续子序列和定义为:
subSum(i, j)=A_i +A_i+1+ … +A_j−1+Aj
试求解输入数组的连续子序列和的最大值。如果所有的整数都是负数,那么最大连续子数列和为0。
例如:
{1, -3, 4, 5}的最大子数列为{4, 5},因为4+5最大;
{3, 4, -5, 8, -4}的最大子数列为{3, 4, -5, 8},因为3+4-5+8最大为10;
{4, 3, -1, 2}的最大子数列为{4, 3, -1, 2},因为4+3-1+2最大为8。
解法一:三层循环
int maxSubSum1( const vector<int> &a )
{
int maxSum = 0;
for( int i = 0; i < a.size(); i++ )
for( int j = i; j < a.size(); j++ )
{
int thisSum = 0;
for( int k = i; k <= j; k++ )
thisSum += a[k];
if( thisSum > maxSum )
maxSum = thisSum;
}
return maxSum;
}
解法二:二层循环
int maxSubSum2( const vector<int> &a )
{
int maxSum = 0;
for(int i = 0; i<a.size(); i++)
{
int thisSum = 0;
for( int j = i; j<a.size(); j++)
{
thisSum += a[j];
if( thisSum > maxSum )
maxSum = thisSum;
}
}
return maxSum;
}
解法三:一层循环
int maxSubSum3( const vector<int> &a )
{
int maxSum = 0, thisSum = 0;
for( int j = 0; j < a.size(); j++ )
{
thisSum += a[j];
if( thisSum > maxSum ) //记录最优值
maxSum = thisSum;
else if( thisSum < 0 ) // 抛弃和为负数的前缀序列
thisSum = 0;
}
return maxSum;
}
解法四:递归方法
int maxSumRec( const vector<int> &a, int left, int right)
{
if( left == right ) //Base case
if( a[left] > 0 )
return a[left];
else
return 0;
int center = ( left + right ) / 2;
int maxLeftSum = maxSumRec( a, left, center );
int maxRightSum = maxSumRec( a, center+1, right );
int maxLeftBorderSum = 0, leftBorderSum = 0;
for( int i = center; i >=left; i-- )
{
leftBorderSum += a[i];
if( leftBorderSum >maxLeftBorderSum )
maxLeftBorderSum = leftBorderSum;
}
int maxRightBorderSum = 0, rightBorderSum = 0;
for( int j = center+1; j <= right; j++ )
{
rightBorderSum += a[j];
if( rightBorderSum > maxRightBorderSum )
maxRightBorderSum = rightBorderSum;
}
return __max( __max(maxLeftSum, maxRightSum),
maxLeftBorderSum + maxRightBorderSum );//3者最大
}
体验到不同算法的规模和时间了吧,所以开发出更加实用的算法会使问题得到更好的解决!!!
- 算法枚举
- 算法递归
- 分治策略
- 贪心策略
- 搜索策略