题目1
实现一种算法,删除单向链表中间的某个节点(即不是第一个或最后一个节点),假定你只能访问该节点。*
示例:
输入:单向链表a->b->c->d->e->f中的节点c
结果:不返回任何数据,但该链表变为a->b->d->e->f
解
- 结点d的值换到结点c上
- 该节点,指向原来的d结点的下一个:e结点
class Solution {
public:
void deleteNode(ListNode* node) {
ListNode* pnext = node->next;
node->val = pnext->val;
node->next = pnext->next;
delete pnext;
}
};
题2
合并两个有序链表,将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
迭代法:
解1
设置四个结点的指针:p1、p2、p3、p4;
p1指向链表L1头节点
p2指向链表L1第二个结点作标记,便于p1、p2结点的后移
p3初始化为空;同样作为标记节点
p4指向链表L2头节点
排序过程是逐个比较链表1(p1)和链表2(p4)的结点,若p1结点比p4小,则插入到结点p4前,否则p4后移,详细过程如下:
-
设置循环条件:链表p1、p4结点均不等于空,循环内部:
a.若p1结点值>=p4结点值:p4结点后移
b.若p1结点值<p4结点值:p1结点插入到链表L2的p4结点前一个,p1指向链表L1下一个结点(p1 = p2;p2 = p2->next) -
循环结束,p1、p4至少有一个指NULL
-
若p1=NULL,说明链表L1已全部结点已插入到L2中,
-
若p4=NULL,则将L1剩余的已有序的结点拼接到L2后面即可
L1:0 2 4 7 9 L2:1 3 4
初始:
0<1,p1结点插入p4前,p1、p2后移;
2 > 1,p3、p4后移
2 < 3,2插入到3前面,p1、p2后移
4 > 3,p3、p4后移;
4 = 4,p3、p4后移
结束循环,p4为空,则将L1拼接到L2后面,排序成功。
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
//1. 定义指针
if(l1 == NULL) return l2;
if(l2 == NULL) return l1;
ListNode* p1(NULL);
ListNode* p2(NULL);
ListNode* p3(NULL);
ListNode* p4(NULL);
p1 = l1;
p2 = l1->next;
p3 = NULL;
p4 = l2;
while(p1 != NULL && p4 != NULL)
{
if(p4->val <= p1->val)
{
p3 = p4;
if(p4 != NULL)
p4 = p4->next;
}
else
{
if(p3 == NULL)
{
p1->next = p4;
l2 = p1;
}
else
{
p3->next = p1;
p1->next = p4;
}
p3 = p1;
p1 = p2;
if(p2 != NULL)
p2 = p2->next;
}
}
if(p4 == NULL)
{
p3->next = p1;
}
return l2;
};
解2
- 设置1结点,并初始化(设值-1),prev、pHead指向它;
- 设置循环结束条件:l1、l2均不指向空,循环内部:
a. 比较l1和l2结点大小
b. prev->next指向较小那个结点
c. prev指向gai节点,该节点的指针后移(l1或l2) - 循环结束,哪个指针不为空,拼接到prev后面
- 返回pHead->next
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
// 迭代算法
ListNode* pHead = new ListNode(-1);
ListNode* prev = pHead;
while(l1 != NULL && l2 != NULL)
{
//l1<=l2,prev下一节点l1;prev=l1,l1后移;;
if(l1->val <= l2->val)
{
prev->next = l1;
prev = l1;
l1 = l1->next;
}
else
{
prev->next = l2;
prev = l2;
l2 = l2->next;
}
}
if(l1 == NULL)
prev->next = l2;
else
prev->next = l1;
return pHead->next;
}
};
递归算法:
递归调用:
若l1<l2:mergeTwoLists(l1->next,l2)
若l1>=l2:mergeTwoLists(l1,l2->next)
结束条件:
l1为null:返回l2;
l2为null:返回l1;
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1 == NULL)
return l2;
if(l2 == NULL)
return l1;
if(l1->val < l2->val)
{
l1->next = mergeTwoLists(l1->next,l2);
return l1;
}
else
{
l2->next = mergeTwoLists(l1,l2->next);
return l2;
}
}
};