一、对算法分析方法的最简单的理解和使用方法

1、首先大家可能一般会被那些数学的概念搞晕,其实简单理解下来,就是假设任何语句执行的效率都是一样的,所以设定每一个语句的执行时间都是一个时间单位,那么只要计算这个程序到底执行了多少语句,就可以算出其时间复杂度。

2、其次就是我们要明白,我们是个估算,所以可以进行化简,明显我们可以忽略那些相对来说低阶的项,只分洗最高阶项。然后主要就是有这些常见的法则:

(1)FOR循环

一次for循环的运行时间至多是该for循环内语句的运行时间乘以迭代次数。

(2)嵌套的FOR循环

肯定是计算最内层循环语句的执行次数,然后再乘以所以循环的迭代次数。

(3)整个程序

其实找到循环迭代次数最多,嵌套最多的进行计算就好。

3、当然,我们计算的只是大概值,而且为了计算的简便,我们一边进行适当的放大,即只考虑最坏最坏的情况,算出其时间复杂度即可。

二、最大子序列

书中通过4种不同的解法来进一步强化我们应该如何计算时间复杂度,小白我也好好学习了下,在此写下学习笔记。

题目:算出一个整数序列中最大的子序列的值。

算法一:

int MaxSubsequenceSum1(const int A[],int N)

{

int thisSum , MaxSum;

MaxSum=0;

for (int i =0; i<N; i++)

{

for (int j=i; j<N; j++)

{

thisSum=0;

for (int K =i; K<=j; K++)

{

thisSum+=A[K];

}

if(thisSum>MaxSum)

{

MaxSum=thisSum;

}

}

}

if(MaxSum==0)

{

int i;

for(i=0;i<N;i++)

{

if(A[i]!=0)

break;

}

if(i!=N)

{

int Max=A[0];

for(int j=0;j<N;j++)

{

if(A[j]>Max)

{

Max=A[j];

}

}

MaxSum=Max;

}

}

return MaxSum;

}

我们可以看出其最大的for循环有三重,而且最坏的可能迭代次数都是N,所以我们可以很容易的得出,此算法的时间复杂度为O(N^3),其中资源最明显的浪费就在重复计算了从低i到第k的子序列的值,所以算法二便是进行了简单的修改。
算法二:

int MaxSubsequenceSum2(const int A[],int N)

{

int thisSum,MaxSum;

MaxSum=0;

for (int i=0; i<N; i++)

{

thisSum=0;

for (int j=i; j<N; j++)

{

thisSum+=A[j];

if(thisSum>MaxSum)

{

MaxSum=thisSum;

}

}

}

if(MaxSum==0)

{

int i;

for(i=0;i<N;i++)

{

if(A[i]!=0)

break;

}

if(i!=N)

{

int Max=A[0];

for(int j=0;j<N;j++)

{

if(A[j]>Max)

{

Max=A[j];

}

}

MaxSum=Max;

}

}

return MaxSum;

}

其实改变的地方即使采用的累加的策略而已,但却使效率大大的提高了,所以这里也是提高算法效率的一个小小的技巧,即尽力减少不必要的计算,尽量利用现有的计算结果。
算法三:

int Max3(const int a,const int b,const int c)

{

int temp = (a>b)?a:b;

temp=(temp>c)?temp:c;

return temp;

}

int MaxSubSum(const int A[],int Left,int Right)

{

int MaxLeftSum,MaxRightSum;

int MaxLeftBorderSum,MaxRightBorderSum;

int LeftBorderSum,RightBorderSum;

if(Left==Right)

{

if(A[Left]>0)

return A[Left];

else

return 0;

}

int center=(Right+Left)/2;

MaxLeftSum=MaxSubSum(A, Left, center);

MaxRightSum=MaxSubSum(A, center+1, Right);

LeftBorderSum=MaxLeftBorderSum=0;

for(int i=center;i>=Left;i--)

{

LeftBorderSum+=A[i];

if(LeftBorderSum>MaxLeftBorderSum)

{

MaxLeftBorderSum=LeftBorderSum;

}

}

RightBorderSum=MaxRightBorderSum=0;

for(int i=center+1;i<=Right;i++)

{

RightBorderSum+=A[i];

if (RightBorderSum>MaxRightBorderSum)

{

MaxRightBorderSum=RightBorderSum;

}

}

return Max3(MaxLeftSum,MaxRightSum,MaxLeftBorderSum+MaxRightBorderSum);

}

int MaxSubsequenceSum3(const int A[],int N)

{

int MaxSum = MaxSubSum(A, 0, N-1);

if(MaxSum==0)

{

int i;

for(i=0;i<N;i++)

{

if(A[i]!=0)

break;

}

if(i!=N)

{

int Max=A[0];

for(int j=0;j<N;j++)

{

if(A[j]>Max)

{

Max=A[j];

}

}

MaxSum=Max;

}

}

return MaxSum;

}

这个算法使用了分治的思想,还有递归的思想,即把一个问题不断的分解成类似的规模更小的子问题来解决,所以这里我们要求一个序列的最大子序列,其实就是求左半部分,有伴部分和中间部分的最大子序列,而求左半部分,后半部分的最大子序列显然是将问题的规模变小了,所以可以递归使用,直到剩下一个数的情况.而中间部分呢,则取左右两边,左边从右往左,右边从左往右的最大子序列。然后加起来作为中间部分的值,最后比较中间部分,左半部分,后半部分三部分的值就可以得到结果啦。

算法四:

int MaxSubsequenceSum4(const int A[],int N)

{

int thisSum,MaxSum;

thisSum = MaxSum=0;

for(int i=0;i<N;i++)

{

thisSum+=A[i];

if(thisSum>MaxSum)

{

MaxSum=thisSum;

}

else if(thisSum<0)

{

thisSum=0;

}

}

if(MaxSum==0)

{

int i;

for(i=0;i<N;i++)

{

if(A[i]!=0)

break;

}

if(i!=N)

{

int Max=A[0];

for(int j=0;j<N;j++)

{

if(A[j]>Max)

{

Max=A[j];

}

}

MaxSum=Max;

}

}

return MaxSum;

}

最后一个算法就比较牛逼啦,这个算法竟然只是N阶的,大家可以想想这个算法的速度有多快,而且如果不考虑全是负数的情况的话,还可以做到随时读入,随时释放内存的强大功能,在此深深膜拜一下。

转载于:https://www.cnblogs.com/BlueMountain-HaggenDazs/p/3898352.html

《数据结构与算法分析》学习笔记(二)——算法分析相关推荐

  1. 数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配

    数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配 引入小题:最短路径 最大流问题(maximum flow problem) ...

  2. 数据结构与算法学习笔记之 提高读取性能的链表(上)

    数据结构与算法学习笔记之 提高读取性能的链表(上) 前言 链表(Linked list)比数组稍微复杂一点,在我们生活中用到最常见的应该是缓存,它是一种提高数据读取性能的技术,常见的如cpu缓存,浏览 ...

  3. 数据结构与算法 学习笔记(5):字符串

    数据结构与算法 学习笔记(5)- 字符串 本次笔记记录了LeetCode中关于字符串的一些问题,并给出了相应的思路说明和代码.题目编号与LeetCode对应,方便查找. 题目1:LeetCode 13 ...

  4. 数据结构与算法学习笔记——图 C++实现

    数据结构与算法学习笔记--图 C++实现 1 概念 2 图的表示方法 3 算法 3.1 拓扑排序 3.2 图的搜索算法 3.2.1 广度优先搜索(BFS) 3.2.2 深度优先搜索(DFS) 3.3 ...

  5. wxpython应用程序对象与顶级窗口_wxPython学习笔记(二)

    如何创建和使用一个应用程序对象? 任何wxPython应用程序都需要一个应用程序对象.这个应用程序对象必须是类wx.App或其定制的子类的一个实例.应用程序对象的主要目的是管理幕后的主事件循环. 父类 ...

  6. 数据结构与算法学习笔记之先进先出的队列

    前言 队列是一种非常实用的数据结构,类似于生活中发排队,可应用于生活,开发中各个方面,比如共享打印机(先请求先打印),消息队列.你想知道他们是怎么工作的么.那就来一起学习一下队列吧 正文 一.队列的定 ...

  7. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7851 ...

  8. [转载]dorado学习笔记(二)

    原文地址:dorado学习笔记(二)作者:傻掛 ·isFirst, isLast在什么情况下使用?在遍历dataset的时候会用到 ·dorado执行的顺序,首先由jsp发送请求,调用相关的ViewM ...

  9. PyTorch学习笔记(二)——回归

    PyTorch学习笔记(二)--回归 本文主要是用PyTorch来实现一个简单的回归任务. 编辑器:spyder 1.引入相应的包及生成伪数据 import torch import torch.nn ...

  10. tensorflow学习笔记二——建立一个简单的神经网络拟合二次函数

    tensorflow学习笔记二--建立一个简单的神经网络 2016-09-23 16:04 2973人阅读 评论(2) 收藏 举报  分类: tensorflow(4)  目录(?)[+] 本笔记目的 ...

最新文章

  1. 为什么我们喜欢用 sigmoid 这类 S 型非线性变换?
  2. Build Docker image of a Python Flask app【转载】
  3. Ext JS 4.1.1 RC2发布
  4. 在计算机网络系统的远程通信中,在计算机网络系统的远程通信中,通常采用的传输技术是...
  5. mysql ab复制延时_Mysql的AB复制
  6. mysql sqlite 性能优化_MySQL和Sqlite3性能测试
  7. 8004.ros2中添加boost依赖库写法
  8. [二分][贪心]JZOJ P3996 Sabotage
  9. java 爬虫 sessionid_java爬虫实战之模拟登陆
  10. 基于单片机的“彩灯控制器”的程序设计与调试
  11. IDEA MyEclipse Eclipse 快捷键大全(最终版)
  12. 阿里P7级别面试经验总结,面试心得体会
  13. VRay Next for SketchUp 赋予材质常见问题
  14. C++之AStar寻路算法
  15. 无变压器的最简单开关稳压电源
  16. [经验教程]2022京东618红包活动时间是什么时候开始什么时候结束及怎么领取京东618红包?
  17. 启动修复无法修复计算机win10,win10系统使用“sfc /scannow”修复系统提示Windows资源保护无法启动修复服务怎么办...
  18. Vue3 composition-apisetup 生命周期
  19. 看WIZ110SR如何实现串口转以太网功能
  20. 我真的改变了很多,QQ群里同学们说的

热门文章

  1. SJXXX串口扩展芯片 4串口芯片 UART串口芯片
  2. win2008r2 AD用户账户的批量导入方法
  3. shell编程中date用法(转)
  4. POJ 1852 Ants 分析
  5. 【Android车载系统 News | Tech 1】News 谷歌开发车载Android系统 2014-12-19
  6. [其它] - 为什么中国的程序员技术偏低
  7. 简单解释什么是 依赖注入 和 控制反转
  8. Golang 特性简介
  9. 关于Android错误 View requires API level 14 (current...
  10. (转)告别程序员生涯,一点感慨,与诸君共勉