代码运行可以参考根目录下README.md中的程序调试和main.cpp

题目标题不能直接跳转,需要把项目拉到本地用编译器打开后才能跳转,或者去仓库里找对应路径的代码文件

1.合并有序链表

将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来两表的存储空间,不另外占用其他的存储空间。表中不允许有重复的数据。

输入:

1
2
4
1
3
4

输出:

1
2
3
4

 

 

2.求两链表交集

已知两个链表A和B分别表示两个集合,其元素递增排列。请设计一个算法,用于求出A与B的交集,并将结果存放在A链表中。

输入:

1
2
3
4
5
6
7
2
3
5
7

输出:

2
3
5
7

 

 

 

3.分割链表

设计算法将一个带头结点的单链表A分解成两个具有相同结构的链表B和链表C,其中B表的节点为A表中值小于0的节点,而C表的节点为A表中值大于0的节点(链表A中的元素为非零整数,要求B、C表利用A表的节点)

4.查找链表最大值

设计一个算法,通过一趟遍历确定长度为n的单链表中值最大的节点。

 

5.反转链表

设计一个算法,将链表中所有节点的链接方向“原地”逆转,即要求仅利用原表的存储空间,换句话说,要求算法的空间复杂度为O(1)

6.求两链表差集

已知两个链表A和B分别表示两个集合,其元素递增排列。请设计一个算法,用于求出A与B的差集,并将结果存放在A链表中。

7.数组左移

2010年真题

设将n(n>1)个整数存放到一维数组R中。试设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0<p<n)个位置,即将R中的数据由(X0,X1,...,Xn-1)变换为(Xp,Xp+1,...,Xn-1,X0,X1,...,Xp-1)。 要求:

  1. 给出算法的基本设计思想。

  2. 根据设计思想,采用C或C++语言描述算法,关键之处给出注释。

  3. 说明你所设计算法的时间复杂度和空间复杂度。

解答:

  1. 可以将这个问题视为把数组ab转换成数组ba(a代表数组的前p个元素,b代表数组中余下的n-p个元素),先将a逆置得到a-1b, 再将b逆置得到a-1b-1 最后将整个a-1b-1逆置得到(a-1b-1)-1 = ba。

    设Reverse函数执行将数组元素逆置的操作,对abcdefgh向左循环移动3(p=3)个位置的过程如下:

    注: Reverse中, 两个参数分别表示数组中待转换元素的始末位置。

  2. 代码如下:

  3. 上述算法的时间复杂度为O(n), 空间复杂度为O(1)。

8.寻找两正序数组中位数

2011年真题

一个长度为L(L≥1)的升序序列S,处在第 L/2个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现在有两个等长升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。要求:

  1. 给出算法的基本设计思想

  2. 根据设计思想,采用C、C++或Java语言描述算法,关键之处给出注释

  3. 说明你说设计算法的时间复杂度和空间复杂度

解答:

  1. 分别求两个升序序列A、B的中位数,设为a和b。若a=b,则a或b即为所求中位数;否则,舍弃a、b中较小者所在序列之较小一半,同时舍弃较大者所在序列之较大一半,要求两次舍弃的元素个数相同。在保留的两个序列中,求新的中位数,重复上述过程,直到两个序列中均只含一个元素时为止,则较小者为所求的中位数。

  2. 代码如下:

  3. 时间复杂度为O(logn), 空间复杂度为O(1)。