力扣链表题分享

合并俩个有序链表

方法一:创建一个节点,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;
}
  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值