目录
1.移除链表元素
分析
代码
2.合并两个有序链表
分析
代码
1.移除链表元素
分析
像这种移除元素的,加个哨兵位头节点会比较方便,因为旧的头会有被移除的情况,不好控制。这里只需要用cur指向待遍历的节点,prev指向cur的前一个节点就可以。考虑到有连续被删除的节点,所以判断相等应该在循环里进行。
如果相等,跳出来以后,要考虑三种情况:
1.cur是空,prev是空,prev一开始是指向空的。
2.prev是空,cur不是空。
3.prev不是空,cur随便。
不相等,prev往后走,cur往后走就好。
代码
/**
* Definition for singly-linked list.
* 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) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if(head==nullptr)
{
return head;
}
ListNode* dummy = new ListNode(0);
dummy->next = head;
ListNode* cur =head;
ListNode* prev = nullptr;
while(cur)
{
if(cur->val==val)
{
while(cur&&cur->val == val)
{
cur=cur->next;
}
if(prev==nullptr&& cur==nullptr)
{
return nullptr;
}
if(prev==nullptr)
{
dummy->next=cur;
prev=cur;
}
else
prev->next=cur;
}
else
{
prev=cur;
cur=cur->next;
}
}
if(prev==nullptr)
{
return nullptr;
}
ListNode* newnode = dummy->next;
delete dummy;
return newnode;
}
};
2.合并两个有序链表
分析
1.考虑两个链表都为空
2.考虑一个链表为空一个链表不为空
3.考虑两个都不为空,声明两个指针代替两个链表的头节点进行遍历,哪个节点val值小就进行尾插,尾插后该指针往后走。跳出条件是有一个指针走到空。剩下的节点都是升序了,直接尾插就好。
代码
/**
* Definition for singly-linked list.
* 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) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
if(list1==nullptr && list2==nullptr)
{
return nullptr;
}
if(list1==nullptr)
{
return list2;
}
if(list2==nullptr)
{
return list1;
}
ListNode* cur = nullptr;
ListNode* l1=list1;
ListNode* l2=list2;
while(l1&&l2)
{
if(l1->val < l2->val)
{
if(cur!=nullptr)
{
cur->next=l1;
}
cur=l1;
l1=l1->next;
}
else
{
if(cur!=nullptr)
{
cur->next=l2;
}
cur=l2;
l2=l2->next;
}
}
if(l1)
{
cur->next=l1;
}
else
{
cur->next=l2;
}
ListNode* newnode = list1->val < list2->val ? list1 : list2;
return newnode;
}
};