leetcode打卡day04---链表

160.两个链表的交点

leetcode160
解题思路:

设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a。同样的距离,同样的速度,则一定可以找到公共节点。
当访问 A 链表的指针访问到链表尾部时,令它从链表 B 的头部开始访问链表 B;同样地,当访问 B 链表的指针访问到链表尾部时,令它从链表
A 的头部开始访问链表 A。这样就能控制访问 A 和 B 两个链表的指针能同时访问到交点。

如果不存在交点,那么 a + b = b + a,以下实现代码中 l1 和 l2 会同时为 null,从而退出循环。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *l1=headA,*l2=headB;
        while(l1!=l2){
            l1=(l1==NULL)?headB:l1->next;
            l2=(l2==NULL)?headA:l2->next;
        }
        return l1;
    }
};

206.反转链表

leetcode206
动画演示

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        //迭代
        // ListNode *pre=NULL;
        // ListNode *cur=head;
        // while(cur!=NULL){
        //     ListNode *tmp=cur->next;
        //     cur->next=pre;
        //     pre=cur;
        //     cur=tmp;
        // }
        // return pre;
        //递归
        if(head==NULL||head->next==NULL) return head;
        ListNode *next=head->next;
        ListNode *newhead=reverseList(next);
        next->next=head;
        head->next=NULL;
        return newhead;

    }
};

21.合并两个有序链表

leetcode21

/**
 * 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* 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;
        // }
        //暴力解法
        ListNode *head=new ListNode(-1);
        ListNode *h=head;
        while(l1!=NULL&&l2!=NULL){
            if(l2->val<l1->val){
                h->next=l2;
                l2=l2 ->next;
            }else{
                h->next=l1;
                l1=l1->next;
            }
            h=h->next;
        }
        h->next=(l1==NULL)?l2:l1;
        return head->next;
    }
};

**

2.链表相加

leetcode2

/**
 * 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* addTwoNumbers(ListNode* l1, ListNode* l2) {
    //虚拟头节点
        ListNode *head=new ListNode(-1);
       ListNode *h=head;
       int sum=0;//两个链表的和
       bool carry=false;//进位
       while(l1!=NULL||l2!=NULL){
           sum=0;
           if(l1!=NULL){
               sum+=l1->val;
               l1=l1->next;
           }
           if(l2!=NULL){
               sum+=l2->val;
               l2=l2->next;
           }
           if(carry){
               sum+=1;
           }
           h->next=new ListNode(sum%10);
           h=h->next;
           carry=sum>=10?true:false;
        }
        //如果最后有进位,末尾补1;[添加链接描述](https://leetcode-cn.com/problems/add-two-numbers/)
        if(carry){
            h->next=new ListNode(1);
        }
        return head->next;
    }
};

链表中环的入口节点

题目描述:

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

解题思路:

设置双指针,一个慢指针,一个快指针,慢指针一次移动一步,快指针一次移动两步,如果链表中存在环,则一定会相遇,当第一次相遇后,将快指针设置为头节点,然后快指针和慢指针每次移动一步,则下次相遇一定是环的入口节点;

代码实现

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if(pHead==nullptr||pHead->next==nullptr) return nullptr;
        ListNode *p1=pHead;
        ListNode *p2=pHead;
        //快指针和快指针->next不为空;
        while(p2&&p2->next){
            p1=p1->next;
            p2=p2->next->next;
            if(p1==p2) break;
        }
        //if(!p2||!p2->next) return nullptr;
        p2=pHead;
        while(p2!=p1){
            p2=p2->next;
            p1=p1->next;
        }
        return p1;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值