0
点赞
收藏
分享

微信扫一扫

保研机试备考三:链表操作

狗啃月亮_Rachel 2022-04-30 阅读 41
链表c++

保研机试备考三:链表操作

AcWing 66. 两个链表的第一个公共结点

题目

https://www.acwing.com/problem/content/62/

思路

一开始想着暴力做, O ( n 2 ) O(n^{2}) O(n2)的遍历两个链表,发现TLE了。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *findFirstCommonNode(ListNode *headA, ListNode *headB) {
        ListNode *p=headA,*q;
        for(;p!=NULL;p=p->next)
        {
            for(q=headB;q!=NULL;q=q->next)
            {
                if(q==p)
                    return p;
            }
        }
        return p;
    }
};

看了y总的讲解,顿悟。
在这里插入图片描述
指针p从headA开始走,如果走到尾巴了,从headB开始走
指针q从headB开始走,如果走到尾巴了,从headA开始走
假设两条链表从头到第一个公共的节点的长度分别为 a a a b b b,公共的那部分长度为 l l l

  • 如果 a = = b a==b a==b,则他们的公共节点就是第一次相遇的点,此时p走了a,q走了b
  • 如果 a ! = b a!=b a!=b,则他们的公共节点是他们再出发后的点,也是第一次相遇的点,此时p走了 a + l + b a+l+b a+l+b,q走了 b + l + a b+l+a b+l+a,所以无论如何都会相遇
  • 如果两条链表没有公共节点,那么他们会一起走向空节点,走的距离都是 a + b ( a ! = b ) a+b(a!=b) a+b(a!=b),或者 a ( a = = b ) a(a==b) a(a==b)

代码

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

AcWing 3756. 筛选链表

题目

https://www.acwing.com/problem/content/3759/

思路

  • 1: 两重遍历即可解决
  • 2: 利用哈希表,只遍历一遍解决

代码

两重遍历:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* filterList(ListNode* head) {
        ListNode *p,*q,*t,*s=head;
        for(p=head;p!=NULL;p=p->next)
        {
            for(q=p,t=p->next;t!=NULL;)
            {
                if((t->val==p->val)||(t->val+p->val==0))
                {
                    q->next=t->next;
                    free(t);
                    t=q->next;
                }
                else
                {
                    q=t;
                    t=t->next;
                }
            }
        }
        return s;
    }
};

哈希表只遍历一遍:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* filterList(ListNode* head) {
        bool st[10010];
        memset(st,0,sizeof(st));
        st[abs(head->val)]=true;
        auto p=head->next,s=head,q=head;
        while(p)
        {
            if(st[abs(p->val)])
            {
                q->next=p->next;
                free(p);
                p=q->next;
            }
            else
            {
                st[abs(p->val)]=true;
                q=p;
                p=p->next;
            }
        }
        return s;
    }
};

AcWing 3757. 重排链表

题目

https://www.acwing.com/problem/content/3760/


思路

把要插入到前面的节点的值保存下来,往原来的链表里插就好,记得插之前把要插的点在链表里先去除掉。

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void rearrangedList(ListNode* head) {
        vector<int> rev;  //把要往前插的节点存下来
        ListNode *p=head,*q;
        int count=0;    //算出有多少个节点
        while(p)
        {
            rev.push_back(p->val);
            count++;
            p=p->next;
        }
        reverse(rev.begin(),rev.end());
        int pp=count-count/2;
        for(int i=0;i<pp;i++) rev.pop_back();    //去除不用往前插的节点
        
        auto t=head;             //在链表中把相应的尾巴去掉
        for(int i=1;i<pp;i++)
            t=t->next;
        t->next=NULL;
       
        
        p=head;                                      //开始插入节点
        for(int i=0;i<rev.size();i++)
        {
            q=(ListNode*)malloc(sizeof(ListNode));
            q->val=rev[i];
            q->next=p->next;
            p->next=q;
            p=q->next;
        }
    }
};

举报

相关推荐

0 条评论