文章目录
- 一、选择题
- 二、编程题
一、选择题
1、在单链表中,要将s所指结点插入到p所指结点之后,其语句应为(D )
A. s.next=p+1; p.next=s;
B. p.next=s; s.next=p.next
C. s.next=p.next; p.next=s.next;
D. s.next=p.next; p.next=s;
答案解析:D
把s指向的结点插入到p所指向的结点之后,首先要保证链表不断链,就需要先把s指向的结点和p后年的结点链接起来,代码为
s.next=p.next;
最后让p的下一个结点指向s即可,代码为p.next=s
2、下述有关栈和队列的区别,说法错误的是 (D )
A. 栈是限定只能在表的一端进行插入和删除操作。
B. 队列是限定只能在表的一端进行插入和在另一端进行删除操作。
C. 栈和队列都属于线性表
D. 栈的插入操作时间复杂度都是o(1),队列的插入操作时间复杂度是o(n)
答案解析:D
栈的插入操作时间复杂度都是o(1),因为栈只允许在表的某一端进行操作
队列的插入操作时间复杂度是o(1),队列的入队操作也只允许在表的其中一端
3、输入序列是ABC,输出序列变为BCA时,经过的栈操作为(B )
A. push,push,push,pop,pop,pop
B. push,push,pop,push,pop,pop
C. push,pop,push,push,pop,pop
D. push,push,pop,pop,push,pop
答案解析:B
上题中,整个入栈和出栈的过程可以为,A先入栈(push),B入栈(push),B出栈(pop),C入栈(push),C出栈
(pop),A出栈(pop),所以整个过程为:push,push,pop,push,pop,pop
4、栈的特点是先入先出,这种说法(B )
A. 正确 B. 错误
答案解析:B
说法错误。栈的特点为先入后出
5、一个队列的入队序列为 1234 ,则队列可能的输出序列是(A )
A. 4321
B. 1234
C. 1432
D. 3241
答案解析:B
队列的特点是先入先出原则,入队顺序为1234,那么出队顺序和入队顺序是一样的
二、编程题
1、合并链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。OJ链接
示例1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例2:
输入:l1 = [], l2 = [0]
输出:[0]
【解题思路】:
这道题目课上反复讲过,一共有两种思路来解决。
1.递归法,利用好方法的语义,判断当前l1和l2的头结点的大小,将剩余结点和另外整个链表的合并操作交给子函数处理。
2.原地移动,在遍历l1和l2的时候尾插新的合并链表。
class Solution {
// 1.递归法
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list1 == null) {
return list2;
}
if (list2 == null) {
return list1;
}
if (list1.val <= list2.val) {
// 说明此时要把list1.next和整个list2交给merge
// 然后将结果拼接到list1.next
list1.next = mergeTwoLists(list1.next,list2);
return list1;
}else {
list2.next = mergeTwoLists(list1,list2.next);
return list2;
}
}
// 2.原地移动
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
// 边界
if (list1 == null) {
return list2;
}
if (list2 == null) {
return list1;
}
// 此时l1和l2都不为空
ListNode dummyHead = new ListNode(101);
ListNode last = dummyHead;
while (list1 != null && list2 != null) {
if (list1.val <= list2.val) {
last.next = list1;
last = list1;
list1 = list1.next;
}else {
last.next = list2;
last = list2;
list2 = list2.next;
}
}
// 此时l1或l2为空
if (list1 == null) {
last.next = list2;
}else {
last.next = list1;
}
return dummyHead.next;
}
}
2、删除链表中重复的结点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表 1->2->3->3->4->4->5 处理后为 1->2->5 OJ链接
示例1:
输入:{1,2,3,3,4,4,5}
返回值:{1,2,5}
示例2:
输入:{1,1,1,8}
输出:{8}
【解题思路】:
这道题难点有两个。1.如何判断重复结点(使用cur和next引用来判断),prev一定指向待删除结点的前驱(prev一定不是
待删除的结点)。2.删除多个重复结点(prev.next = next).
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
ListNode dummyHead = new ListNode(-1);
dummyHead.next = pHead;
ListNode prev = dummyHead;
ListNode cur = prev.next;
while (cur != null) {
ListNode next = cur.next;
if (next == null) {
// 当前链表只有一个结点
return dummyHead.next;
}else {
if (cur.val != next.val) {
prev = prev.next;
cur = cur.next;
}else {
while (next != null && cur.val == next.val) {
next = next.next;
}
// 此时next指向第一个不重复的结点
prev.next = next;
cur = next;
}
}
}
return dummyHead.next;
}
}