重拾程序设计题

重拾程序设计题

  今天是情人节,我竟然乖乖地去想明白一个题目。。。终于被我想明白了,也是比较高兴的,因为我昨晚对优化的第二种解法想不明白

  昨晚跟某强闲聊,说在练习python题,计算:1+2+..+(n-1)+n的和,一开始以为他是不记得python语法,所以很久都弄不出来,老实说,裸打我也不记得,不仅python,C的语法我也挺模糊。。。

  后来才发现他说是没想到怎么解决,也就是解题的逻辑,我就说人是怎么思考解决的,转化为计算机能懂的语言(编程),就行了。

  之后就推荐他看看程序设计的题目,一开始不需要写,但是要想,而且尽力想明白(这个过程我知道是很辛苦的啦,过来人,苦闷、无聊、郁闷...不过坚持下去,逻辑思维能力、读题理解能力等肯定会有一个质的提升)。最后扔了两个题目网址给他:

(1)https://leetcode-cn.com/problemset/all/   ---- 职场人刷题多

(2)http://poj.org/problemlist ---- 学生党多

  (今天才发现以前在里面刷了300+题目的杭电oj竟然不再对外开放了,有点伤感)

  为了督促自己,我也希望这篇文章之后,坚持每天或者每周思考一些程序设计的题目。脑袋瓜不用真是容易用进废退的,然后买来的书不看也是劳民伤财的

#######################  上面都是废话

一、问题

  临睡之前,我看了一条题,来自《算法竞赛入门经典》的第1章 例题18 开放式学分制(对应 UVa 11078),为什么选了这条题,因为题目够短

  这里不给出源代码,只有伪代码,哈哈哈,因为我不记得怎么写了

  我先简化下题目:

  给出n个整数的序列:A0,A1,。。。。,An-1,现在需要从中找出两个整数 Ai 和 Aj(i < j),使得Ai - Aj 尽量大

【输入格式】

  每组数据的第一行为整数的个数n(2 <= n <= 100000),以下n行,每行末一个绝对值不超过150 000 的整数

【输出格式】

  输出 Ai - Aj 的最大值

 

二、问题分析

  1、最容易想到的解决方法:两个for循环去解决

  伪代码如下:

1 ans=A[0] - A[1]
2 
3 for (i=0; i < n; i++)
4     for (j = i+1; j < n; j++)
5         ans = max(ans, A[i] - A[j])
6 
7 print ans

  从A0开始,比较A1,。。。An-1 与A0 的差值;然后下一个循环,A1开始,比较A2。。。An-1 与 A1 的差值,不断重复这个过程。

  要算的次数:(n-1) + (n-2) + ...+2+1= n*(n-1)/2

  也就是时间复杂度为: O(n^2)

  要是提交这个代码,TLE跑不掉(Time Limit Exceeded)

  俺不纠结这个,大部分人都能想到的。然后看了第二种方法,书中写的特别拗口:对于每个固定的 j,我们应该选择的是 小于 j 且 Ai 最大的 i,而和 Aj 的具体数值无关。 这样,我们从小到大枚举 j, 顺便维护 Ai 的最大值即可。

  一脸懵逼。。。不知所云,不明觉厉

 

  2、优化算法 O(n)

  我先举一个整数序列,就容易明白了:

-5 3 8 -2 8 9 -16 -1 -1 

 

   是不是人眼一看就知道 9 - (-16)是最大的,因为我们选了一个Ai 最大的值,也就是整数9,Aj 的值我们不管它大小,想想Aj固定的情况下,Ai 是不是应该越大越好?所以上面红字就说跟 Aj 无关。

   对于每一个Aj来讲,假设扫描到 -16。我们是不是要比较 -16 之前 哪个Ai 是最大的,然后跟 Aj 做差,来获取一轮的 Ai - Aj。

   然而这还不够,我们要维护一个在Aj 之前,也就是Aj-1,前面序列的: Ai - Aj-1 的最大值。例如,当遍历到-16这个数时,要知道 -5 到 9 这个序列(-5 3 8 -2 8 9)的最大 Ai - Aj 

   所以,每扫描一个A[j],应更新 A[i] 的最大值,且得到 A[i] - A[j-1] 的最大差值。每遍历一个数都能获得当前两个值的最大值,扫描到最后就是最终结果

      伪代码贴下:

ans = A[0] - A[1]
MaxAi = A[0]
for ( j = 1; j < n; j++) ans = max(ans, MaxAi - A[j]) MaxAi = max(A[j], MaxAi) print ans

  如果还有啥不懂,欢迎交流~~~

  希望自己也能捡回这个想题的习惯吧,这玩意还是挺有意思的,能锻炼:

(1)读题、理解能力  ——》理解需求(工作、或者别人交待的问题),理解清楚,这个是基础

(2)英文(有些题库是国外,纯英语)  ——》 英文还是不能落下

(3)算法解题  ——》 工作问题或者生活问题怎么想的,怎么解决的思路

(4)优化能力  ——》 有基本解题思路,还要想想如何更优处理,不要TLE之类的,实际工作中就是节省时间和空间成本

时间类比成,跑一个代码结果一天都跑不下来的,想想就很郁闷>_<||

空间可以理解为,魂斗罗游戏设计只有100多k(https://www.zhihu.com/question/50076174/answer/1101330430),节省很多硬盘空间,短小精悍

 

posted @ 2022-02-14 22:40  windysai  阅读(22)  评论(0编辑  收藏  举报