剑指offer(十六)——合并两个排序的链表
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
题解
这道题的思路很简单,但是不知道怎么做,看了大佬的答案后理解了。
一解:
递归
public static ListNode Merge(ListNode list1,ListNode list2) {
if(list1 == null) {
return list2;
}else if (list2 == null) {
return list1;
}else {
if (list1.val <= list2.val) {
list1.next = Merge(list1.next, list2);
return list1;
}else {
list2.next = Merge(list1, list2.next);
return list2;
}
}
}
理解起来还是挺容易的,两个链结点进行比较,当前结点值较小的链进行移动,并且当前结点接下一个结点。用图象来表示比较好理解:
- 链1和链2当前结点比较,链1结点值更小,于是链1进行移动并且链 1的当前结点接下一个结点,并返回当前结点,链2不动。
- 链1和链2进行比较,链2结点值更小,于是链2进行移动,当前结点接下一个结点,并返回当前结点,链1不动。
- 这就是一个递归。
二解:
非递归:
public static ListNode Merge(ListNode list1,ListNode list2) {
if (list1 == null) {
return list2;
}
if (list2 == null) {
return list1;
}
ListNode head = null;
ListNode list = null;
while(list1 != null && list2 != null) {
if (list1.val <= list2.val) {
if (head == null) {
head = list = list1;
}else {
list.next = list1;
list = list.next;
}
list1 = list1.next;
}else {
if (head == null) {
head = list = list2;
}else {
list.next = list2;
list = list.next;
}
list2 = list2.next;
}
}
if (list1 == null) {
list.next = list2;
}else {
list.next = list1;
}
return head;
}
两者的思路是一样的,只不过递归显然更加简洁。非递归的话就需要额外用到两个指针,一个指针用来指向链头,另一个用来移动,下面还是用图来表示:
- 首先判断其中一条链为空的情况。
- 然后在不为空的情况下,同递归的情况一样去判断,但是首先得确定链头,链1比链2结点值小,因此链1第一个结点作为链头,并进行移动。
- 此时链2比链1小,因此list的下一个结点就是链2的第一个结点,并移动链2。
- 最后在其中一条链结束时,链尾接上另一条链的最后部分即可。