leetcode 21. 合并两个有序链表

大耗子 2021年02月19日 11次浏览

题目:21. 合并两个有序链表

21. 合并两个有序链表

难度简单

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例 1:

img

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

提示:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1l2 均按 非递减顺序 排列

解题思路

递归

通过返回后续链表的最小结点,当前结点去链接起来就可以了。

迭代

通过一个临时结点tmp指向合并了的链表的尾结点,然后将两个链表中的最小结点链接到tmp的后面,tmp重新指向尾结点。

代码

ListNode* initList(int start, int num, int gap)
{
	srand(time(NULL));
	ListNode* head0 = new ListNode(start);
	ListNode* head = head0;
	for (int i = 1; i < num; i++)
	{
		ListNode* mNode = new ListNode(start + i * gap);
		head0->next = mNode;
		head0 = head0->next;
	}
	return head;
}


struct ListNode {
	int val;
	ListNode *next;
	ListNode() : val(0), next(nullptr) {}
	ListNode(int x) : val(x), next(nullptr) {}
	ListNode(int x, ListNode *next) : val(x), next(next) {}
};

void printList(ListNode* head) {
	while (head) {
		cout << head->val << "  ";
		head = head->next;
	}
	cout << endl;
}


class Solution {
public:
	ListNode* mergeTwoLists1(ListNode* l1, ListNode* l2) {
		// 如果都为空,返回另一个指针与NULL都一样
		// 如果有一个为空,另一个也没有递归的必要了,没啥可排序的
		if (!l1) return l2;
		if (!l2) return l1;
		// 如果是l2比较小, 将小的节点返回出去
		if (l1->val > l2->val) {
			// 链接后面链表给的最小的节点
			l2->next = mergeTwoLists(l1, l2->next);
			return l2;
		}
		// 链接后面链表给的最小的节点
		l1->next = mergeTwoLists(l1->next, l2);
		return l1;
	}

	ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
		// 如果都为空,返回另一个指针与NULL都一样
		// 如果有一个为空,另一个也没有递归的必要了,没啥可排序的
		if (!l1) return l2;
		if (!l2) return l1;
		ListNode head(0);
		ListNode *tmp = &head; // tmp为合并好的链表的尾结点

		while (l1 && l2) {
			if (l1->val < l2->val) {
				tmp->next = l1;
				l1 = l1->next;
			}
			else {
				tmp->next = l2;
				l2 = l2->next;
			}
			tmp = tmp->next;
		}
		if (l1)
			tmp->next = l1;
		else
			tmp->next = l2;
		return head.next;
	}
};

int main()
{
	ListNode * list1 = initList(1, 5, 3);
	ListNode * list2 = initList(2, 5, 2);
	Solution sln;
	printList(list1);
	printList(list2);
	ListNode * ret = sln.mergeTwoLists(list1, list2);
	printList(ret);
	
	return 0;
}