代码随想录Day 4 链表

24两两交换链表中的节点

本题技巧是添加dummy head
我把我的解题思路归纳为两个步骤:

  1. 确定好循环结束条件,需要分奇数偶数,即需要考虑链表中节点的个数;
  2. 在循环体内进行交换操作时,要注意添加temp指针(我的理解是:当某个指针改变其指向时,原来的next指针就需要用temp保存起来。

话不多说,直接上C++代码:

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode *dummy = new ListNode();
        dummy->next = head; 
        // cur这个节点指针每次指向需要交换的两个节点的前一个节点
        ListNode * cur = dummy;
        //当链表节点为偶数个,恰好两两一组相互交换;当为奇数个,最后一个节点不用交换; 
        // 这里注意偶数判断情况(cur->next != nullptr )要写在前面
        while(cur->next != nullptr && cur->next->next != nullptr){
             ListNode * temp1 = cur->next;
             ListNode * temp2 = cur->next->next->next;
             cur->next = cur->next->next;
             cur->next->next = temp1;
             temp1->next = temp2;
             cur = cur->next->next;
        }
        return dummy->next;
    }
};

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

本题的关键是找到倒数第N个节点的位置,以及记录该节点的前一个节点。本题技巧是使用双指针+ dummy head。
题目中已描述N大于等于1且小于等于链表长度。当N等于链表长度时,需要删除头节点,我们添加dummy head可以将删除头节点时的情况转换为删除一般节点的情况。添加双指针则是为了定位到待删除节点的位置。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode * dummy = new ListNode();
        dummy->next = head;
        // 先定义两个指针
        ListNode * fast = dummy;
        ListNode * slow = dummy;
        // 让fast指针先走n步,由于fast一开始指向dummy head,在走了n步之后,停留在原链表的第n个节点处
        while(n-- && fast!=nullptr){
            fast = fast->next;
        }
        // fast和slow两个指针同时移动,当fast指向链表的最后一个节点时,slow刚好指向待删除节点的前一个位置
        // 这里要判断fast->next还是fast要根据上面fast到底走了多少步来确定(如果上面fast走了n+1步,那么这里要判断fast != nullprt)
        while(fast->next != nullptr){
            fast = fast->next;
            slow = slow->next;
        }
        slow->next = slow->next->next;
        return dummy->next;
    }
}

160链表相交

解法一:哈希集合

一个一个对比两个链表中是否有内存地址相等的元素;

解法二: 双指针

定义p1和p2两个指针分别指向两个headA和headB两个链表,让两个指针同时移动。
假设headA长度为m,headB长度为n,如果相交,则重合部分长度为k:

(1)m == n且不相交: 两个指针移动m个

(2)m != n且不相交: 两个指针移动m+n个

(3)m == n且相交: 两个指针移动m-k个

(4)m != n且相交: 两个指针移动m+n-k个

public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode * pa = headA;
        ListNode * pb = headB;
        while(pa != pb){
            // if(pa->next == NULL && pb->next == NULL){
            //     return NULL;
            // }
            pa = pa ? pa->next : headB;  //如果判断条件是pa->next,需要上面注释的判断,否则对于无相交情况是死循环
            pb = pb ? pb->next : headA;
        }
        // 当两链表不相交时,pa=pb=nullptr; 当相交时,此时pa=pb,都指向最开始相交的那个节点
        return pa;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值