千山鸟飞绝,春风吹又生。
简单来说就是对问题寻求分界,将分界之后的问题分别进行解决。
注意第二点,对每一个子集合进行排序,实际上就是问题继续细分的地方
简单来说,先将这个数组进行1.分割,随后对2.其中的每个元素进行排序,3.将排序好了的两个有序数组进行合并,4.如果无法分割,直接进行排序。
其中,2中的排序本身又是123的重复(分割成更小,排序,归并)
其实a和b都只是数组而已,只不过是被我们用某些参数分了阶段,递归的过程,可以用不断地将两个小部分合成为二倍地长度并且重新储存来概括,也就是图片中的这样。
简单来说就是一个归并的过程,只不过是在同一个数组中进行(其实在不在是没有影响的)
第二部分,就是将剩余部分进行整体的移动,因为已经排过序所以不用考虑顺序的问题。
这里递归有一个作用就是,在递归进行的过程中,实际上当函数返回开始排序的时候,数组中的元素已经不是调用排序的时候的样子,而是改变了,但是定位是不会变的,始终都是精确的关系。
这里要注意的是,倒数第二个的地方条件实际上是反了,如果是小于n的话,才是应该直接传递,否则不可能继续进行递归。
精髓在于,首先找到左边第一个大于的,然后是右边第一个小于的,然后进行交换,如果顺序倒位就返回。
其实选择问题追求的不是有序,只是一个数而已
关键是最后一句,如果当前的点正好就是那个数字的话就可以返回了
如果大于就到左边找k大,如果小于就到右边减去当前值找k1大
所谓的拥有更好的平均性能,就是这种方法不一定是排序完整个中间过程,但是如果是先排序后查找,那肯定是不行的,所以是<nlogn的水平
从17章开始实际上讨论的都是最优化问题,解决这个问题可以通过贪婪算法,也可以通过动态规划,而对于可以明确指出优化函数(换句话说,就是达成目的有明确的方法)的问题,一般采取贪婪算法
所谓的拓扑排序其实不是排序啊,也就是将一群数组从一个固定的规则中选择出一个随即顺序而已,此外,这也不是图论相关,仅仅是在数组中对于数组操作而已
这里的重要步骤,用设定好了的迭代器对此顶点进行迭代,只要取出来的下一个顶点的数字,就将其indegree减一,然后如果已经为0,就压进去
综述一下,就是首先从出发点选出所有的边,然后将最小的选进去,然后在当前这个最小边的基础上,看看其所能到达的边,如果这些边不存在就进行更新,如果存在就比较,代价小的情况下再进行更新,然后继续选当前代价最小的边,存入,继续循环
主要就三个数组,一个用来记录对应点的距离,一个用来记录对应点的前一个点,一个用来记录当前所有可以选择的点,所以基本上都是按照点来对应数组中的元素的,没有什么绕
精髓的操作,一个是将邻接的点的前置点进行更新,一个是将其对应的最短距离进行更新,最后,将这个点进行候选的储存
总的复杂度是n2级别
这里的重点就是是否会产生环边的问题,环边,其实也就是——在这个边被选定的时候,实际上这个点已经存在于这个图中了,只是没有这条边,换句话说,从已知的图到此点是有一个路径的,只是不是你当前选定的这个路径甚至可能不是单条路径,但是你又找出一条,这就是环路,也就是说,对于我们新找出来的一条边来说,首先考察,如果两个点已经处在同一个子图,那么就不行,如果不是,那么就可以连接,并且连接之后两者变成一个子图。
这使用并查集来实现
此外,由于每次要进行的是最小边的选取,所以是选择小根堆来进行数组的初始化比较好
终于复习完一章了,感觉并没学到什么东西,有点儿要命
都说按部就班是最好的努力方法,其实最好的努力方法应该是按部就班外加偶尔拼命,可惜,年轻人,你的路走窄了
不过没关系,继续吧,接下来是图论知识。
15章