【读书笔记】《挑战程序设计竞赛》

《挑战程序设计竞赛》


前言

坚持就是胜利,本人使用语言java


一、蓄势待发–准备篇

1.5.1 算法复杂度

【读书笔记】《挑战程序设计竞赛》
详细总结来源

1.6.1 O(nlogn)三角形问题

【读书笔记】《挑战程序设计竞赛》

O(nlogn)方法:

  1. 将边按照从小到大顺序进行排序;
  2. 从大到小进行搜索,如果,edge[i],edge[i+1],edge[i+2]能构成三角形,即为周长对大的三角形;

原因:
三角形条件: A<B+C (其中A是最长的边);
要使得周长最长,B+C要尽可能的大;
排序后的B+C剩下边里面的最大,如果不满足,则没有边可以边满足B+C>A,即对A而言,不存在三角形;如果满足,则是最大周长的三角形;

1.6.2 蚂蚁问题

【读书笔记】《挑战程序设计竞赛》
【读书笔记】《挑战程序设计竞赛》
思路:智力题,开动你的小脑经!!

1.6.3 抽签问题(四数之和)

【读书笔记】《挑战程序设计竞赛》

问题描述:数组中是否存在: a+b+c+d = m
解决方案:看成前两个数之和与后两个数之和,利用二分查找,效率为(O(n^2logn)

练习

leetcode18. 四数之和

博客中使用:先排序;双指针(O(n^3)),回溯法(利用条件会剪枝)

二、初出茅庐–初级篇

2.1 “穷竭搜索”–暴力

穷竭搜索:将所有的可能性列出来,在其中寻找答案
递归:自己调用自己

数据结构:

栈Stack(LIFO):push;pop;peek;
队列Queue(FIFO):offer;poll;peek;

遍历方法:

深度优先遍历(DFS):深入;栈;(解数独)
宽度优先遍历(BFS):周围;队列 (最短路径,最少操作)

2.1.4 DFS–水洼的数量

【读书笔记】《挑战程序设计竞赛》
思路:

  1. 八联通的则为水洼,需遍历一个单位附近的八个单位并将它们都改成’.’;
  2. dfs遍历到尽头,并将这些联通的W全部改掉;W连接的所有W都替换成了’.’;
  3. 直到图中不再存在W为止,执行dfs的次数即为水洼的个数。

练习

leetcode200. 岛屿数量

2.1.5 BFS–迷宫最短路径

【读书笔记】《挑战程序设计竞赛》【读书笔记】《挑战程序设计竞赛》

问题:N*M规格迷宫;起点S;终点G;墙壁#;通道.;寻找一条最短路径从起点到达终点

思路:

  1. 本题要求最短距离,可用 d[N][M] 数组保存距离,INF 初始化;将起点的距离设置成0;
  2. 将上下左右(可移动,是通道)的距离为当前点的距离+1,并且加入队列;
  3. 读取队列中节点,BFS遍历上下左右,直到遇见终点或者所有节点访问完成;
  4. 如果是遇见终点,即为最短距离;如果点访问结束,则不可达;

2.1.6 next_permutation(begin(nums), end(nums))

按照字典序给出nums数组的下一个排列顺序;
C++语言中可以用来跟方便的获取下一个排列顺序;java没有

练习

31. 下一个排列

2.1.7 剪枝

暴力中,有时候解空间很大,深度DFS,有时候很早可以根据某些条件直接跳过,剪枝,来缩小解空间;

2.2 一直向前!–贪心

贪心:不断贪心地选取当前最优的策略
我的经验:主要是看问题贪心选择后能不能变成一样的贪心子问题

2.2.1 硬币问题

【读书笔记】《挑战程序设计竞赛》
思想: 优先兑换面值大的硬币

2.2.2 区间问题

【读书笔记】《挑战程序设计竞赛》
【读书笔记】《挑战程序设计竞赛》

思想: 在可选的工作当中,每次都选择结束时间最早的工作

2.2.3 字典序最小问题

【读书笔记】《挑战程序设计竞赛》

思想: 不断取S开头末尾较小的字符放在T末尾,如果相同,比较S与反转S’的字典序,选择较小方向字符的放在T末尾;

2.2.4 其他问题

【读书笔记】《挑战程序设计竞赛》

思想: 向右遍历尽可能远的选择点,实现覆盖,这样最后获得最少的点
【读书笔记】《挑战程序设计竞赛》
【读书笔记】《挑战程序设计竞赛》

思想: 类比于哈夫曼树,最短的木板最远,最后加权路径和最小;

2.3 动态规划DP

动态规划(DP):不断贪心地选取当前最优的策略
我的经验:真难get,md

2.2.1 硬币问题