一、合并两个排序的链表
1、题目
2、解法
这个采用递归的解法可能比较容易理解。
1、重点在于原问题到子问题的分解,即两个链表1和2从头节点开始进行遍历,并比较两个链表的节点值,小的那个节点应该作为新链表3的当前节点,并指定它的下一个节点;
2、假如链表1的节点小,那么新链表3的当前节点应该是merge(list1->next,list2)的结果;如果链表2的节点小也是一样;
3、边界条件:当两个链表都为空时,返回空节点;任意一个链表为空时,返回另一个链表。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
if (pHead1 == nullptr && pHead2 == nullptr) return nullptr;
if (pHead1 == nullptr) return pHead2;
if (pHead2 == nullptr) return pHead1;
if (pHead1->val > pHead2->val){
pHead2->next = Merge(pHead1, pHead2->next);
return pHead2;
}
else{
pHead1->next = Merge(pHead1->next, pHead2);
return pHead1;
}
}
};
二、反转链表
1、题目
2、解法
我感觉链表的递归算法比较难理解,这道题我认为采用迭代法/三指针法更容易理解。
1、首先考虑特殊情况,如果为空链表,直接返回空节点即可;
2、要反转链表,就是在遍历链表的过程中,让当前节点的next等于前一节点即可,那我们可以定义三个节点:pre,cur,temp分别记录当前节点的前一节点、当前节点、当前节点的后一节点。
3、初始值pre=nullptr,cur=pHead,然后当cur不为空节点的条件下遍历,用temp记录当前节点的下一节点cur->next,再令当前节点cur指向前一节点pre,即cur->next = pre,并更新pre和cur,让两者都向后移动一个节点,即pre = cur,cur = temp。
4、需要注意的是,由于初始值pre=nullptr,第一次遍历以后头节点的next就变为nullptr,符合反转链表以后的尾节点的next为空的要求。另外遍历到最后一次时,pre为反转链表的头节点,而cur为空节点,因此要返回的时pre。
C++代码如下:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if (pHead == nullptr) return nullptr;
ListNode* cur = pHead;
ListNode* pre = nullptr;
while (cur != nullptr){
ListNode* temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};