LeetCode刷题|day4 链表

24. 两两交换链表中的节点 - 力扣(LeetCode)

注意事项:

要想节点两两交换节点,一定要让一个指针指向反转两个节点的前一个节点;

使用虚拟头结点解此题,程序实现分为遍历和交换;

cur指向头结点,如果链表的节点数为奇数,cur->next->next=NULL时,遍历结束;若链表的节点数为偶数,cur->next=NULL,遍历结束。

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummyhead = new ListNode(0);
        dummyhead->next = head;
        ListNode* cur = dummyhead;
        while(cur->next!=NULL&&cur->next->next!=NULL)
        {
            ListNode* temp=cur->next;
            ListNode* temp1 = cur->next->next->next;
            cur->next = cur->next->next;
            cur->next->next = temp;
            temp->next=temp1;
            cur = cur->next->next;
        }
        return dummyhead->next;
    }
};

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

关键:找到倒数第n个节点

注意事项:

  1. 要想删除当前节点,操作指针要指向当前节点的前一节点;

  1. 倒数第n个节点的寻找,使用虚拟头结点的技巧和双指针法;定义一个快指针和一个慢指针,让快指针先移动n步,然后快慢指针同时移动,直到快指针指向空节点,那么慢指针指向了要删除的节点;由注意事项1可得,应让快指针移动n+1步,然后快慢指针同时移动,这样慢指针就指向了要删除节点的前一个节点

  1. 需要对删除节点进行释放

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head == nullptr || head->next == nullptr) return NULL;
        ListNode* dummyhead = new ListNode(0);
        dummyhead->next = head;
        ListNode* fast = head;
        ListNode* slow = dummyhead;
        for(int i = 0; i<n; i++)
        {
            fast = fast->next;
        }
        while(fast)
        {
            fast = fast->next;
            slow = slow->next;
        } //节点释放与删除操作
        ListNode* temp = slow->next;
        slow->next = temp->next;
        delete temp;
        return dummyhead->next;
    }
};

160. 相交链表 - 力扣(LeetCode)

注意:此题是求解两个链表交点节点的指针,交点不是数值相等,而是指针相等!

求出两个链表的长度,并求出两个链表的差值,然后让curA移动到和curB末尾对齐的位置;

比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA==curB,则找到交点;否则返回空指针。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* curA = headA;
        ListNode* curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != NULL) { // 求链表A的长度
            lenA++;
            curA = curA->next;
        }
        while (curB != NULL) { // 求链表B的长度
            lenB++;
            curB = curB->next;
        }
        curA = headA;
        curB = headB;
        // 让curA为最长链表的头,lenA为其长度
        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;
    }
};

142. 环形链表 II - 力扣(LeetCode)

使用快慢指针法解此题;

第一步:判断列表是否有环;分别定义fast和slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果fast和slow指针在途中相遇,说明这个链表有环;

第二步:如果有环,如何找到这个环的入口

相遇时,slow指针走过的节点数为x+y,fast指针走过的节点数为x+y+n(y+z);因为fast指针是一次走两个节点,slow指针一次走一个节点,所以2*(x+y)=x+y+n(y+z);若要找到环形入口节点,那么x表示头结点到环形入口的距离,整理得x=(n-1)(y+z)+z;当n=1时,x = z;从头结点出发一个指针,从相遇节点出发一个指针,这两个节点每次只走一个节点,那么当这两个指针相遇的时候就是环形入口的节点。

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast!=NULL && fast->next!=NULL) //判断是否有环
        {
            fast = fast->next->next;
            slow = slow->next;
            if(slow == fast) //寻找环的入口
            {
                ListNode* index1 = fast;
                ListNode* index2 = head;
                while(index1!=index2)
                {
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index2;
            }
        }
        return NULL;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值