排序的定义
假设含有n个记录的序列为{r1,r2,…,rn},其相应的关键字分别是{k1,k2,…,kn},需要确定1,2,…,n的一种排列p1,p2,…,pn,使其相应的关键字满足kp1<=kp2<=…<=kpn 非递减(或非递增)的关系,即使得序列成为一个按关键字有序的序列{rp1,rp2,…,rpn},这样的操作就称为排序[1]。
简单来说,排序就是使输入的序列变成符合一定规则(关键字)的有序序列(非递减或非递增)。大多数遇到的排序问题都是按数据元素值的大小规则进行排序的问题。所以本文为了方便起见,只讨论数据元素值大小比较的排序问题。
排序的稳定性
假设ki=kj(1<=i《=n,1<=j<=n,i!=j),且在排序前的序列中ri领先于rj(即i 简单来概括稳定和不稳定[2]: 时间和空间复杂度 排序算法可以分成两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序。 线性时间非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此称为线性时间非比较类排序。 基本思想 比较相邻的两个元素,将值大的元素交换到右边(降序则相反) 步骤: 比如有n个元素,那么第一次比较迭代,需要比较n-1次(因为是相邻成对比较,最后一个元素没有与下一个相邻比较的对象,所以是n-1次),此次迭代完成后确定了最后一个元素为最大值;第二次比较迭代,需要比较n-2次,因为第一次迭代已经确定好了最后一个元素,所以不再需要比较;…;第 i次比较迭代,需要比较n-i次,此时确定后面i个元素是有序的较大元素;…;第n-1次比较迭代,需要比较n-(n-1)次,此时完成冒泡排序操作。 时间复杂度:o(n^2) = (n-1)*(n-1) 动图演示: **过程演示:**待排序数组:{5, 4, 7, 1, 6, 2},升序排序 --------------------------------------- 第一次循环: 第一次比较5和4,5>4,交换位置:{4,5,7,1,6,2} 第二次比较5和7,5 第三次比较7和1,7>1,交换位置:{4,5,1,7,6,2} 第四次比较7和6,7>6,交换位置:{4,5,1,6,7,2} 第五次比较7和2,7>2,交换位置:{4,5,1,6,2,7} 第一次循环完成结果:{4,5,1,6,2,7} ---------------------------------------- 第二次循环: 第一次比较4和5,4 第二次比较5和1,5>1,交换位置:{4,1,5,6,2,7} 第三次比较5和6,5 第四次比较6和2,6>2,交换位置:{4,1,5,2,6,7} 第五次比较6和7,6 第二次循环完成结果:{4,1,5,2,6,7} ---------------------------------------- 第三次循环: 第一次比较4和1,4>1,交换位置:{1,4,5,2,6,7} 第二次比较4和5,4 第三次比较5和2,5>2,交换位置:{1,4,2,5,6,7} 第四次比较5和6,5 第五次比较6和7,6 第三次循环完成结果:{1,4,2,5,6,7} ---------------------------------------- 第四次循环: 第一次比较1和4,1 第二次比较4和2,4>2,交换位置:{1,2,4,5,6,7} 第三次比较4和5,4 第四次比较5和6,5 第五次比较6和7,6 第三次循环完成结果:{1,2,4,5,6,7} ---------------------------------------- 第五次循环: 第一次比较1和2,1 第二次比较2和4,2 第三次比较4和5,4 第四次比较5和6,5 第五次比较6和7,6 第三次循环完成结果:{1,2,4,5,6,7} 相信看完上面的演示过程,你对冒泡排序过程及原理有了完全的理解,但是细心的朋友应该会发现其实在第四次循环就已经得到了最终的结果,这么来看第五次循环完全是多余的,于是就有冒泡排序的改进版本:当某一轮循环当中没有交换位置的操作,说明已经排好序了,就没必要再循环了,break退出循环即可。 复杂度分析: 代码实现: bubble_sort.cpp 参考: 1 经典排序算法之冒泡排序 2 (图示版):来、通俗聊聊冒泡排序 基本思想 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 步骤 n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下: 动图演示 复杂度分析 时间复杂度:O(n2) 注:无论什么数据进去,选择都是O(n2)的时间复杂度,所以若要使用它,建议数据规模越小越好。 空间复杂度:O(1) 代码实现 selection_sort.cpp 基本思想 插入排序(insertion sort)又称直接插入排序(staright insertion sort),其是将未排序元素一个个插入到已排序列表中。对于未排序元素,在已排序序列中从后向前扫描,找到相应位置把它插进去;在从后向前扫描过程中,需要反复把已排序元素逐步向后挪,为新元素提供插入空间。 步骤 动图演示 复杂度分析 举个例子(暴力手绘图) 代码实现 基本思想 设待排序元素序列有n个元素,首先取一个整数increment(小于n)作为间隔将全部元素分为increment个子序列,所有距离为increment的元素放在同一个子序列中,在每一个子序列中分别实行直接插入。 注:在希尔排序算法提出之前,排序算法的时间复杂度都为O(n^2),如冒泡排序、选择排序和插入排序。而希尔排序算法是突破这个时间复杂度的第一批算法之一。该复杂度为O(nlogn),其实直接插入排序算法的改进版,也称为缩小增量排序。希尔排序是直接插入排序的一种改进,减少了其复制的次数,速度要快很多。原因是,当n值很大时,数据项每一趟排序需要移动的个数很少,但数据项的距离很长;当n值减小时,每一趟需要移动的数据增多。正是因为这两种情况的结合才使得希尔排序效率比插入排序高很多。 步骤 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述: 注:增量的初始值一般为序列长度的一半,然后之后每次再自身减半。 动图演示 上图是不是很难理解,那么来看看这个! 说实话,看了上面两个图,我还是有点不理解,不怕,我又找了下面这幅图像。 简单介绍一下: 对于[592, 401, 874, 141, 348, 72, 911, 887, 820, 283]序列,一共10个元素。 第一次,设置增量为5=10/2,所以有5个子序列:[592,72]、[401,911]、[874,887]、[141,820]和[348,283]。然后对每个子序列进行插入排序,结果是[72,592]、[401,911]、[874,887]、[141,820]和[283,348]。注意,这些元素在序列中的位置初始是不变的,只会随着部分子序列间元素的位置变化而变化,比如[592,72]在原来的序列中索引是[0,5],之后变成了[5,0];而[401,911]的序列索引是[1,6],第一次处理后,索引值不变。 总之,第一次处理的结果是将**[592, 401, 874, 141, 348, 72, 911, 887, 820, 283]—> [72, 401, 874, 141, 283, 592, 911, 887, 820, 348]**。 第二次,设置增量为2=5/2,所以有2个子序列:[72, 874, 283, 911, 820]和[401, 141, 592, 887, 348]。然后对每个子序列进行插入排序,[72, 874, 283, 911, 820]的结果是[72, 283, 820, 874, 911],而[401, 141, 292, 887, 348]的结果是[141, 292, 348, 401, 887]。 总之,第二次处理的结果是将 [72, 401, 874, 141, 283, 592, 911, 887, 820, 348]—>[72, 141, 283, 292, 820, 348, 874, 401, 911, 997]。 第三次,设置增量为1=2/2,所以有1个序列,就是上述生成的序列[72, 141, 283, 292, 820, 348, 874, 401, 911, 997]。然后进行插入排序,其结果为[72, 141, 283, 292, 348, 401, 820, 874, 911, 997]。 总之,第三次处理的结果是将 [72, 141, 283, 292, 820, 348, 874, 401, 911, 997]—>[72, 141, 283, 292, 348, 401, 820, 874, 911, 997]。 其实本质上还是利用了插入排序,但这里通过增量作用,相当于添加了预处理,减少插入排序中移动元素的次数,提高了效率。通过"增量"预处理,使得希尔排序算法时间复杂度降低。 复杂度分析 希尔排序的时间复杂度与增量序列的选取有关。 时间复杂度: 空间复杂度:O(1) 稳定性:不稳定 代码实现 shell_sort.cpp shell_sort.py 参考: 基本思想 堆排序(heap sort):将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。 注:堆排序是一种选择排序,指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 在介绍堆排序之前,先了解一下什么是堆(heap)? 堆 堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图: 同时,我们对堆的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子: 该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是: **大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] ** **小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2] ** ok,了解了这些定义。接下来,我们来看看堆排序的基本思想及基本步骤: 步骤 动图演示 看到这里,你可能还是晕乎乎的,下面看个讲解示例: 步骤一 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。 a.假设给定无序序列结构如下 b.此时我们从最后一个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点 arr.length/2-1=5/2-1=1,也就是下面的6结点),从左至右,从下至上进行调整。 c.找到第二个非叶节点4,由于[4,9,8]中9元素最大,4和9交换。 d.这时交换导致了子根[4,5,6]结构混乱,继续调整,[4,5,6]中6最大,交换4和6。 此时,我们就将一个无需序列构造成了一个大顶堆。 步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。 a.将堆顶元素9和末尾元素4进行交换 b.重新调整结构,使其继续满足堆定义 c.再将堆顶元素8与末尾元素5进行交换,得到第二大元素8. 后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序 再简单总结下堆排序的基本思路: a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆; b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端; c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。 复杂度分析 堆排序整体主要由构建初始堆+交换堆顶元素和末尾元素并重建堆两部分组成。其中构建初始堆经推导复杂度为O(n),在交换并重建堆的过程中,需交换n-1次,而重建堆的过程中,根据完全二叉树的性质,[log2(n-1),log2(n-2)…1]逐步递减,近似为nlogn。所以堆排序时间复杂度一般认为就是O(nlogn)级。 时间复杂度: 空间复杂度:O(n) 稳定性:不稳定 代码实现 参考: 基本思想 归并排序(merge sort): 步骤 基本思想 快速排序(quick sort):通过一趟排序将待排列表分隔成独立的两部分,其中一部分的所有元素均比另一部分的所有元素小,则可分别对这两部分继续重复进行此操作,以达到整个序列有序。(这个过程,我们可以使用递归快速实现) 步骤 快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下: 动图演示 复杂度分析 举个例子(暴力手绘图) 代码实现 注:下面都是利用递归法实现快速排序。 quick_sort.cpp quick_sort.py N-sum就是从序列中找出N个数,使得N个数之和等于指定数值的问题。 2-sum 2-sum就是从序列中找出2个数,使得2个数之和等于0的问题,即a+b=sum。 下面的例子是规定指定数值为0: 上述算法的由于包含了两层循环,因此时间复杂度为O(N^2)。 观察发现,上述算法时间主要花费在数据比对,为此可以考虑使用二分查找来减少数据比对时间,要想使用二分查找,首先应该对数据进行排序,在此使用归并排序或者快速排序对数组进行升序排列。排序所花时间为O(NlogN),排序之后数据查找只需要O(logN)的时间,但是总共需要查找N次,为此改进后算法的时间复杂度为O(NlogN)。 3-sum 上述2-sum的解题思路适用于3-sum及4-sum问题,如求解a+b+c=0,可将其转换为求解a+b=-c,此就为2-sum问题。 为此将2-sum,3-sum,4-sum的求解方法以及相应的优化方法实现在如下所示的sum类中。 sum.h sum.cpp test.cpp 参考资料 TODO ## 将256*256二维数组逆时针旋转90° TODO 深度优先搜索算法(Depth-First-Search,DFS)是一种利用递归实现的搜索算法。简单来说,其搜索过程和"不撞南墙不回头"类似。 广度优先搜索算法(Breadth-First-Search,BFS)是一种利用队列实现的搜索算法。简单来说,其搜索过程和"湖面丢进一块石头激起层层涟漪"类似。 BFS 的重点在于队列,而 DFS 的重点在于递归。这是它们的本质区别。 应用方向 BFS 常用于找单一的最短路线,它的特点是 “搜到就是最优解”,而 DFS 用于找所有解的问题,它的空间效率高,而且找到的不一定是最优解,必须记录并完成整个搜索,故一般情况下,深搜需要非常高效的剪枝(剪枝的概念请百度)。 参考资料 - Coding:单例模式实现(2次) [1](推荐)《大话数据结构》 [2](推荐)十大经典排序算法(动图演示) [3](推荐)轻松搞定十大排序算法(C++版) [4](推荐)从头说12种排序算法:原理、图解、动画视频演示、代码以及笔试面试题目中的应用 [5](推荐)排序算法时间复杂度、空间复杂度、稳定性比较 [6](推荐)十大排序算法和七大查找算法总结(原理讲解和Python代码实现)—(一)排序算法篇 [7] 常见排序算法C++总结 [8] 十大经典排序算法(JavaScript版) [9] 八大排序算法总结(JAVA版) [10] C++代码
排序算法
冒泡排序(Bubble Sort
选择排序(Selection Sort
插入排序(Insertion Sort
希尔排序(Shell Sort
堆排序(heap Sort
归并排序(merge Sort
快速排序(Fast Sort
常见排序算法复杂度
冒泡排序(Bubble Sort)
/* Summary: 冒泡排序
* Author: Amusi
* Date: 208-05-27
*
* Reference:
* http://en.wikipedia.org/wiki/Bubble_sort
* https://github.com/xtaci/algorithms/blob/master/include/bubble_sort.h
* https://zhuanlan.zhihu.com/p/37077924
*
* 冒泡排序说明:比较相邻的两个元素,将值大的元素交换到右边(降序则相反)
*
*/
#include
''' Summary: 冒泡排序
* Author: Amusi
* Date: 208-05-27
*
* Reference:
* http://en.wikipedia.org/wiki/Bubble_sort
* https://github.com/xtaci/algorithms/blob/master/include/bubble_sort.h
* https://zhuanlan.zhihu.com/p/37077924
*
* 冒泡排序说明:比较相邻的两个元素,将值大的元素交换到右边(降序则相反)
*
'''
def BubbleSort(array):
lengths = len(array)
for i in range(lengths-1):
for j in range(lengths-1-i):
if array[j] > array[j+1]:
array[j+1], array[j] = array[j], array[j+1]
return array
array = [1,3,8,5,2,10,7,16,7,4,5]
print("Original array: ", array)
array = BubbleSort(array)
print("BubbleSort: ", array)
选择排序(Selection Sort)
/* Summary: 选择排序
* Author: Amusi
* Date: 208-06-22
*
* Reference:
* https://en.wikipedia.org/wiki/Selection_sort
* https://github.com/xtaci/algorithms/blob/master/include/selection_sort.h
* 选择排序说明:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
*
*/
#include
''' Summary: 选择排序
* Author: Amusi
* Date: 208-06-22
*
* Reference:
* https://en.wikipedia.org/wiki/Selection_sort
*
* 选择排序说明:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
*
'''
def SelectionSort(array):
lengths = len(array)
for i in range(lengths-1):
min_index = i
for j in range(i, lengths):
if array[j] < array[min_index]:
min_index = j
array[i], array[min_index] = array[min_index], array[i]
return array
array = [1,3,8,5,2,10,7,16,7,4,5]
print("Original array: ", array)
array = SelectionSort(array)
print("SelectionSort: ", array)
插入排序(Insertion Sort)
/* Summary: 插入排序(Insertion Sort)
* Author: Amusi
* Date: 2018-07-16
*
* Reference:
* https://en.wikipedia.org/wiki/Insertion_sort
*
* 插入排序(insertion sort)又称直接插入排序(staright insertion sort),其是将未排序元素一个个插入到已排序列表中。对于未排序元素,在已排序序列中从后向前扫描,找到相应位置把它插进去;在从后向前扫描过程中,需要反复把已排序元素逐步向后挪,为新元素提供插入空间。
*
*/
#include
''' Summary: 插入排序(Insertion Sort)
* Author: Amusi
* Date: 208-07-16
*
* Reference:
* https://en.wikipedia.org/wiki/Insertion_sort
* https://www.cnblogs.com/wujingqiao/articles/8961890.html
*
* 插入排序(insertion sort)又称直接插入排序(staright insertion sort),其是将未排序元素一个个插入到已排序列表中。对于未排序元素,在已排序序列中从后向前扫描,找到相应位置把它插进去;在从后向前扫描过程中,需要反复把已排序元素逐步向后挪,为新元素提供插入空间。
*
'''
def InsertionnSort(array):
lengths = len(array)
# 从索引位置1开始
for i in range(1, lengths):
currentValue = array[i] # 当前索引对应的元素数值
preIndex = i-1 # 前一个索引位置
# 循环条件: 前一个索引对应元素值大于当前值,前一个索引值大于等于0
while array[preIndex] > currentValue and preIndex>=0:
array[preIndex+1] = array[preIndex] # 前一个索引对应元素值赋值给当前值
preIndex -= 1 # 前一个索引位置-1
# preIndex+1,实现元素交换
array[preIndex+1] = currentValue
return array
array = [1,3,8,5,2,10,7,16,7,4,5]
print("Original array: ", array)
array = InsertionnSort(array)
print("InsertionnSort: ", array)
希尔排序(Shell Sort)
/* Summary: 希尔排序(Shell Sort)
* Author: Amusi
* Date: 2018-09-23
*
* Reference:
* https://en.wikipedia.org/wiki/Shellsort
* https://www.geeksforgeeks.org/shellsort/
* 希尔排序(shell sort):设待排序元素序列有n个元素,首先取一个整数increment(小于n)作为间隔将全部元素分为increment个子序列,所有距离为increment的元素放在同一个子序列中,在每一个子序列中分别实行直接插入。
*
*/
#include
'''
* Summary: 希尔排序(Shell Sort)
* Author: Amusi
* Date: 2018-09-23
*
* Reference:
* https://en.wikipedia.org/wiki/Shellsort
* https://www.geeksforgeeks.org/shellsort/
* 希尔排序(shell sort):设待排序元素序列有n个元素,首先取一个整数increment(小于n)作为间隔将全部元素分为increment个子序列,所有距离为increment的元素放在同一个子序列中,在每一个子序列中分别实行直接插入。
*
*
'''
def ShellSort(array):
lengths = len(array)
# 初始化gap
gap = lengths//2
# 减少增量,遍历子序列进行插入排序
while(gap > 0):
for i in range(gap, lengths):
#
temp = array[i]
j = i
# 子序列插入排序
while j>=gap and array[j-gap]>temp:
array[j] = array[j-gap]
j -= gap
array[j] = temp
gap = gap//2
return array
array = [1,3,8,5,2,10,7,16,7,4,5]
print("Original array: ", array)
array = ShellSort(array)
print("InsertionnSort: ", array)
堆排序(Heap Sort)
归并排序(Merge Sort)
快速排序(Quick Sort)
/* Summary: 快速排序(Quick Sort)
* Author: Amusi
* Date: 2018-07-28
*
* Reference:
* https://en.wikipedia.org/wiki/Quicksort
*
* 快速排序(quick sort):通过一趟排序将待排列表分隔成独立的两部分,其中一部分的所有元素均比另一部分的所有元素小,则可分别对这两部分继续重复进行此操作,以达到整个序列有序。(这个过程,我们可以使用递归快速实现)
*
*/
#include
''' Summary: 快速排序(Quick Sort)
* Author: Amusi
* Date: 208-07-28
*
* Reference:
* https://en.wikipedia.org/wiki/Quicksort
* https://www.cnblogs.com/wujingqiao/articles/8961890.html
* https://github.com/apachecn/LeetCode/blob/master/src/py3.x/sort/QuickSort.py
* 快速排序(quick sort):通过一趟排序将待排列表分隔成独立的两部分,其中一部分的所有元素均比另一部分的所有元素小,则可分别对这两部分继续重复进行此操作,以达到整个序列有序。(这个过程,我们可以使用递归快速实现)
*
'''
def QuickSort(array, start, end):
lengths = len(array)
i = start
j = end
# 结束排序(左右两索引值见面,即相等,或者左索引>右索引)
if i >= j:
return # 返回空即可
# 保存首个数值(以首个数值作为基准)
# 这个位置很重要,一定要在if i>=j判断语句之后,否则就索引溢出了
pivot = array[i]
# 一次排序,i和j的值不断的靠拢,然后最终停止,结束一次排序
while i < j:
# (从右往左)和最右边的比较,如果>=pivot,即满足要求,不需要交换,然后j-1,慢慢左移,即拿基准值与前一个值比较; 如果值
查找
二分查找
lower_bound
upper_bound
分治与递归
逆序对数
大数相加
大数相乘
贪婪算法
动态规划
背包问题
找零钱问题
最长公共子序列(LCS)
字符串匹配算法
KMP算法
BM算法
Sunday算法
线性表
数组
栈
队列
链表
二叉树
二叉排序树/二叉查找树BST
平衡二叉树
求二叉树的最大高度
二叉树的前序遍历
二叉树打印出最右侧的节点
非递归中序遍历二叉树
求二叉树深度和宽度
链表
找到链表倒数第k个结点
如何判断单链表中是否有环?
翻转链表
手写双向链表
堆
构建堆的复杂度
堆找出第k大元素的复杂度
打印螺旋矩阵
找最小字串
2-sum、3-sum和4-sum问题
int sum_2()
{
int res = 0;
int n = data.size();
for(int i=0; i<n-1; i++)
{
for(int j=i+1; j<n; j++)
{
if(data[i] + data[j] == 0)
{
res ++;
}
}
}
return res;
}
int cal_sum_2()
{
int res = 0;
for(int i=0; i<data.size(); i++)
{
int j = binary_search(-data[i]);
if(j > i)
res++;
}
return res;
}
#ifndef SUM_H
#define SUM_H
#include
#include "Sum.h"
#include
#include "Sum.h"
#include
无序数组a,b 归并排序成有序数组c
二分查找
分治与递归:逆序对数、大数相加、大数相乘
动态规划:背包问题、找零钱问题和最长公共子序列(LCS)
青蛙跳台阶
BFS和DFS解决最短路径
DFS和BFS的区别(优缺点)
数组的最大区间和
迪杰斯特拉 (Dijkstra) 算法
两个栈实现一个队列
- Coding:stoi函数
- Coding:二叉树对称判断(不用额外空间)
- Coding:返回数组中和最大的子串
- Coding:链表局部反转,每两个结点调换下位置(2次)
- Coding:输入一个数组,取一些数出来,使和最大,约束是不能取相邻的元素,有负数,有小数
- Coding:链表反转
- Coding:swap函数
- Coding:输入数组,将正数排到前面,负数在后面
- Coding:设计实现Hashmap
- Coding:求二叉树中节点的最远距离(3次)
- Coding:找数组中位数
- Coding:给一个点的集合和一个值K,把在以k为半径的区域内存在其他点的点列表输出
- Coding:给一个数组,随机等概率删除数组中的一个数,要求高效
- Coding:写个String类,把能想到的构造函数都写出来
- Coding:atoi函数
- Coding:给一个图,给两个结点,求两个结点之间的最短路径
- Coding:单链表,删除值为k的节点
- Coding:二叉树前序遍历
- Coding:给一个上线时间段记录数组,和开始,结束时间,输出所有这段时间内的上下线记录
- Coding:大小端,写个程序判断
- Coding:两个有序链表merge
- Coding:二分查找,有重复,findlast
- Coding:x的y次方
- Coding:链表倒数第k个节点
- Coding:分数转化成小数,循环部分用括号包起来
- Coding:输入一些时间段,输出最大重合数
- Coding:hash数据结构设计
- Coding:n个点的数组,按x轴排序
- Coding:n个点的数组,两个同行或列的点可以移除一个,使最后图中节点最少,返回移除点的索引序列
- Coding:链表尾结点插入头部,操作k次返回
- Coding:给一个数组,能不能分成两个数组,它们平均值相等,能的话返回两个数组
TODO
参考资料
参考