合并俩个有序链表
方法一:创建一个节点,L1和L2同时进行比较,值小的让新节点指向那个节点,同时那个链表往后前进。
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(!l1)
return l2;
if(!l2)
return l1;
struct ListNode head;
struct ListNode* node=&head;
while(l1&&l2)
{
if(l1->val<l2->val)
{
node->next=l1;
l1=l1->next;
}
else
{
node->next=l2;
l2=l2->next;
}
node=node->next;
}
node->next=l1==NULL?l2:l1;
return head.next;
}
方法二:
递归
如果 l1 或者 l2 一开始就是空链表 ,那么没有任何操作需要合并,所以我们只需要返回非空链表。否则,我们要判断 l1 和 l2 哪一个链表的头节点的值更小,然后递归地决定下一个添加到结果里的节点。如果两个链表有一个为空,递归结束。
struct ListNode* mergeTwoLists(struct ListNode* l1, struct 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;
}
}
删除重复元素
创建一个节点node,将node下一节点的值与node的值进行比较,若相等则删除,若不相等则node前进。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* deleteDuplicates(struct ListNode* head)
{
struct ListNode*node=head;
if(!node)
return head;
while(node->next)
{
if(node->val==node->next->val)
{
node->next=node->next->next;
}
else
node=node->next;
}
return head;
}
反转链表
方法一:
链表的反转,创建节点prev,cur,cur指向后面的节点,prev指向前面的节点,将后面的节点的指向前面的节点即可。
方法二:
递归
struct ListNode* reverseList(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode* newHead = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return newHead;
}
环形链表判断
方法一:
判断链表中是否有环,可以使用快慢指针,如果一个链表中有环,那么快指针和慢指针必定相遇。
bool hasCycle(struct ListNode *head)
{ if(!head||!head->next)//防止head为空或者只有头节点
return false;
struct ListNode* prev=head,*cur=head->next;
int flag=1;
while(cur&&prev!=cur)
{
cur=cur->next;
if(flag==1)
{
prev=prev->next;
flag=0;
}
else
flag=1;
if(cur==prev)
return true;
}
if(prev==cur)
return true;
else
return false;
}
相交链表
给定俩个链表,判断它们是否相交,并返回相交的位置
使用双指针pA和pB
每步操作需要同时更新指针pA 和 pB。
如果指针 pA 不为空,则将指针 pA 移到下一个节点;如果指针 pB 不为空,则将指针 pB 移到下一个节点。
如果指针 pA 为空,则将指针 pA 移到链表 headB 的头节点;如果指针 pB 为空,则将指针 pB 移到链表 headA 的头节点。
当指针 pA 和 pB 指向同一个节点或者都为空时,返回它们指向的节点或者null。
当俩个链表相交时
headA 和 headB 的长度分别是 m 和 n。假设链表headA 的不相交部分有 a 个节点,链表 headB 的不相交部分有 b 个节点,两个链表相交的部分有 c 个节点,则有 a+c=m,b+c=n
pA将会与pB相遇
当a≠b时,pB的长度小于pA
可以看到pB最先越过相交的点,然后到达headA,紧接着pA走过尾结点时,到达headB。
当m=n,但headA和headB这俩个链表不相交时,最后pA和pB的值为NULL。
当m不等于n时,headA的长度小于headB
pA会先到达headB,然后pB再到达headA,则有a+b=b+a,最后pA和pB的值都为NULL。
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
if(!headA)
return NULL;
if(!headB)
return NULL;
struct ListNode* pA=headA,*pB=headB;
while(pA!=pB)
{
pA=(pA==NULL)?headB:pA->next;
pB=(pB==NULL)?headA:pB->next;
}
return pA;
}