tomoebzk

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

day4

Leetcode 24 两两交换链表中节点

题目比较简单,定义好虚拟头节点dummyhead开始遍历就行,需要注意判断遍历结束条件

cur->next!=nullptr&&cur->next->next!=nullptr
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode*dummyHead=new ListNode(0);
        dummyHead->next=head;
        ListNode*cur=new ListNode(0);

        cur=dummyHead; 
        while(cur->next!=nullptr&&cur->next->next!=nullptr)
        {
            ListNode*temp=new ListNode(0);
            ListNode*temp1=new ListNode(0);
            temp=cur->next->next->next;
            temp1=cur->next;
            cur->next=cur->next->next;
            cur->next->next=temp1;
            cur->next->next->next=temp;
            cur=cur->next->next;
        }
        ListNode *result=dummyHead->next;
        delete dummyHead;
        return result;
    }
};

Leetcode 19 删除链表的倒数第n个节点

本题第一眼是笨办法,先得到链表总长度size,再转化为删除第size-n个节点的问题,方法一

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode*dummyHead=new ListNode(0);
        dummyHead->next=head;
        ListNode*cur=dummyHead;

        int size=0;
        while(cur->next!=nullptr)
        {
            cur=cur->next;
            size++;
        }
        int index=size-n;
        cur=dummyHead;
        for(int i=0;i<index;i++)
        {
            cur=cur->next;
        }

        cur->next=cur->next->next;
    
        ListNode*result=dummyHead->next;
        delete dummyHead;
        return result;

    }
};

代码随想录采用双指针法,也可以理解为设置一个定长为n的滑动窗口,窗口停止滑动的条件是fast指针到达nullptr

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode*dummyHead=new ListNode(0);
        dummyHead->next=head;
        ListNode*slow=dummyHead;
        ListNode*fast=dummyHead;
        while(n--&&fast!=nullptr)
        {
            fast=fast->next;
        }
        fast=fast->next;
        while(fast!=nullptr)
        {
            fast=fast->next;
            slow=slow->next;
        }

        slow->next=slow->next->next;
        ListNode*result=dummyHead->next;
        delete dummyHead;
        return result;
    }
};

Leetcode 面试题02.07.链表相交

见到这道题的思路就是先得到两个链表的长度,进行比较,长的链表先将cur遍历到短的head位置,将链表按照结尾对其,然后再同时开始遍历,直到两个cur相等位置。整个过程包括sizeA>sizeB、sizeB>sizeA、sizeA=sizeB。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB)
    {
        ListNode*curA=headA;
        ListNode*curB=headB;
        int sizeA=0;
        int sizeB=0;
        int temp=0;
        while(curA!=NULL)
        {
            curA=curA->next;
            sizeA++;
        }
        while(curB!=NULL)
        {
            curB=curB->next;
            sizeB++;
        }
        curA=headA;
        curB=headB;
        int delta=0;;
        if(sizeA>sizeB)
        {
            delta=abs(sizeA-sizeB);
            temp=sizeB;
            while(delta--)
            {
                curA=curA->next;
            }
            while(curA!=curB&&temp--)
            {
                curA=curA->next;
                curB=curB->next;
            }
            if(temp==0)return NULL;
            return curA;
        }
        else if(sizeB>sizeA)
        {
            delta=abs(sizeA-sizeB);
            temp=sizeA;
            while(delta--)
            {
                curB=curB->next;
            }
            while(curB!=curA&&temp--)
            {
                curA=curA->next;
                curB=curB->next;
            }
            if(temp==0)return NULL;
            return curB;
        }
        else 
        {
            temp=sizeA;
            while(curA!=curB&&temp--)
            {
                curA=curA->next;
                curB=curB->next;
            }
            if(temp==0)return NULL;
            return curA;
        }
    }
};

看到代码随想录才知道可以通过交换长短的cur只进行一次遍历,不需要进行分类进行判断。

if (lenB > lenA) {
            swap (lenA, lenB);
            swap (curA, curB);
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        while (gap--) {
            curA = curA->next;
        }
        // 遍历curA 和 curB,遇到相同则直接返回
        while (curA != NULL) {
            if (curA == curB) {
                return curA;
            }
            curA = curA->next;
            curB = curB->next;
        }
        return NULL;

Leetcode 142 环形链表Ⅱ

这道题主要是通过数学方面进行分析,刚开始分析时把它当作一个追击问题,快指针每次走两步,慢指针每次走一步,这样总会在环中相遇,本来向通过计算环的长度来反求出环的入口,但是发现得不到整个链表的长度,卡了很久。

看了代码随想录才知道通过数学来分析

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode*slow=head;
        ListNode*fast=head;
        while(fast!=NULL&&fast->next!=NULL)
        {
            fast =fast->next->next;
            slow=slow->next;
            if(slow==fast)
            {
                ListNode*fast1=fast;
                ListNode*slow1=head;
                while(slow1!=fast1)
                {
                    slow1=slow1->next;
                    fast1=fast1->next;
                }
                return fast1;
            }
            
        }
        return NULL;
    }
};

一般涉及到增删改操作,用虚拟头结点都会方便很多, 如果只能查的话,用不用虚拟头结点都差不多。 对于链表题,想不明白边界条件的时候通过画图能够辅助理解,更好的判断遍历的过程

posted on 2026-01-19 18:39  broderk  阅读(2)  评论(0)    收藏  举报