学长含泪总结《算法分析与设计》笔记!点击开启算法之旅~

一、算法的重要性

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者最大
}

在这里插入图片描述

体验到不同算法的规模和时间了吧,所以开发出更加实用的算法会使问题得到更好的解决!!!

  1. 算法枚举

在这里插入图片描述

  1. 算法递归

在这里插入图片描述

  1. 分治策略

在这里插入图片描述

  1. 贪心策略

在这里插入图片描述

  1. 搜索策略

在这里插入图片描述

接下来和我一起探索算法的奥秘吧!!!继续关注后续的系列~~

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐小多多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值