21.合并两个有序链表(easy)
思路:
连接两个单增的链表,连接完依然有序,就比较两个结点值得大小,谁大就在后面。有了这个基本思路之后,可以在两个链表上分别维护一个指针,用来比较两个指针所指的结点的大小,然后按递增的方式连接。
连接将创建一个新链表,设置指针*p3,那么遍历中两个链表较小的一个连接在p3->next,然后较小链表结点上的指针后移一位,p3后移一位,这样就构成了循环体。
注意一种情况:一个链表遍历完毕,则直接把另一个链表剩余的结点接在新链表尾部即可。
一个小点:为新链表设置一个哨兵结点,结果返回此指针。
class Solution
{
public:
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2)
{
ListNode *p1 = l1;
ListNode *p2 = l2;
//总是指向更小的元素
ListNode *p3 = new ListNode(0);
// 方便结果的返回
ListNode *head = p3;
while (p1 && p2)
{
if (p2->val < p1->val)
{
p3->next = p2;
p3 = p2;
p2 = p2->next;
}
else if (p2->val >= p1->val)
{
p3->next = p1;
p3 = p1;
p1 = p1->next;
}
}
// 链接剩余节点 谁还有剩余就链接谁
p3->next = p1 ? p1 : p2;
return head->next;
}
};
上面的代码在堆上new了一个新链表,也可以在原链表上进行连接:
采用迭代的方式 :
迭代参数:两个链表指针;
终止条件:其中一个链表遍历结束,结点指针为空;
迭代体:把大的接在小的上。
我对迭代的理解:就是一种功能,当我需要这种功能时,就把迭代函数调用一下,在本题中迭代函数就是比较两个链表某对结点的大小,l1比l2小了就拿后面一个l1->next比较,l2比l1->next小了就拿后面一个l2->next比较,直到一个链表遍历结束。参数很好地体现了这一思想。
//双指针,递归,谁小谁在前
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (l1 == nullptr) {
return l2;
} else if (l2 == nullptr) {
return l1;
} else if (l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);//再拿l1->next->val与l2->val比较
return l1;
} else {
l2->next = mergeTwoLists(