方法一:这是我一开始的想法,将链表L2的各个元素与链表L1的元素进行逐一比较,将L2中的数据元素插入L1中的合适位置。
时间复杂度:O(m+n);空间复杂度:O(1)
1)首先,可能要对第一个元素进行插入操作,所以为了统一插入操作,需要创建哨兵;
2)循环终止条件是L2遍历完即nullptr == pWorkNodeL2,但是在循环过程中,L1可能先遍历完,所以要对L1分情况讨论;
3)跳出循环后,要对检测L1是否遍历完。
这是自然而然的想法,但是经验告诉我们类似这种直觉的想法往往可能不是最好的。
方法二:可以将链表合并的过程看做是新链表的创建过程。比较两个链表数据元素的大小,将数据元素值小的结点插入新链表的末尾,直到遍历完其中一个链表,再将另一个链表中的剩余结点拼接到新链表的末尾。
时间复杂度:O(m+n);空间复杂度:O(1)
虽然这个算法的在时间复杂度上并没有什么提升,但是会感觉这个思路很清晰,给人一种豁然开朗的感觉。实现上要注意的和第一种方法差不多,不同的循环终止条件和循环结束后的判断。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode* pHead = new ListNode(0); //创建哨兵结点 ListNode *pTialNode = pHead, *pInsertNode = nullptr; while (l1 && l2) { if (l1->val < l2->val) //比较两个结点数值的大小 { //插入结点 pInsertNode = l1; l1 = l1->next; } else { pInsertNode = l2; l2 = l2->next; } pInsertNode->next = nullptr; pTialNode->next = pInsertNode; pTialNode = pInsertNode; } pTialNode->next = !l1 ? l2 : l1; return pHead->next; } };
如果你有什么其他的方法,欢迎一起交流!
原文地址:https://www.cnblogs.com/zpchya/p/10753439.html
时间: 2024-10-05 05:05:00