ch2_5 链表两两交换节点&&ch2_6删除倒数N的节点

lc24, 两两交换节点

问题关键点;

startNode: 表示两个交换节点的前一个节点, 称作开始节点, 初始位置为虚拟节点;

由于两个交换节点是在变化的, 所以应该在循环中执行:

node1: 表示第一个交换节点;
node2: 第二个交换节点;

交换之前顺序: startNode , node1, node2;
交换之后顺序: startNode, node2, node1;

交换的顺序

       // 交换顺序将开始节点的后一个节点 更新为 node2, 称为新的第一个节点node2;
    

        // 将原始节点node1 的后一个节点更新为原始节点Node2的 后一个节点;

        //  这里的思路是, 先假设 新的第二节点,已经产生;
        // 然后更新 新的第二个节点的后一个节点;
        // 将新的第一个节点的后一个节点更新为node1, 称为新的第二个节点node1;
 
        // 将开始节点 更新为 新的第二个节点node1; 
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummyHead = new ListNode(0);

        ListNode* startNode = dummyHead;

        dummyHead->next = head;

        while(startNode->next != nullptr && startNode->next->next != nullptr  ){
            ListNode* node1 = startNode->next;
            ListNode* node2 = startNode->next->next;

            // 1. 先将开始节点的后一个节点更新为 node2,  称为新的第一个节点;
            startNode->next = node2;

            // 2.  将原始节点Node1的后一个节点更新为 原始node2 的后一个节点;
            // 这里的思路是, 先更新了 新的第二个节点 的后一个节点, 
            // 代表了 Node1 将 成为新的 第二个节点;
            node1->next = node2->next;

            //3. 将新的第一节点node2 后面的一个节点更新为node1, 成为新的第二个节点;
            node2->next  = node1;

            //  将 开始节点 更新为 新的第二个节点;

            startNode = node1;

        }

        return dummyHead->next;
    }
        

    
};

2.删除倒数 第 N 个节点;

思路:

  1. 首先 使用 两个快慢指针 fast, slow, 并确保两者之间的间隔为N,

  2. 让fast 先行走 N 步, 然后 再让 fast, slow 同时移动, 这样 fast 到达结尾时, slow 到达了比他慢的N 步的节点位置, 这个位置便是我们要删除的 倒数第N个节点;

但是, 实践中, 当我们要删除某个节点时, 我们需要定位的位置是 待删除节点的前一个节点;

所有我们要定位的节点位置是, 待删除节点的前一个节点:

怎么办?

  1. 让fast 先行走 N + 1 步, 然后同时移动 fast, slow;

  2. 当 fast 到达结尾时, slow 比fast 慢了 N -1 步,

此时fast 到达了 末尾节点处, 那么slowNode 到达了删除节点的前一个节点了;

2.1 code

struct ListNode{
    int val;
    ListNode* next;

    ListNode(int x): val(x), next(nullptr){}
};


class Solution{
public:

    ListNode*  removeNthFromEnd(ListNode* head, int n){
        ListNode*  dummyHead = new ListNode(0);
        dummyHead->next = head;

        ListNode* fastNode =  new ListNode(0);
        ListNode* slowNode =  new ListNode(0);

        fastNode = dummyHead;
        slowNode = dummyHead;

        int step = n + 1;
        while( step --){  // 让快指针先走n+1 步;  step = 0 时, 循环体不执行;
            fastNode = fastNode->next;
        }

        while( fastNode != nullptr){  // 当fastNode 没有到达,最后一个节点时;
            slowNode = slowNode->next;
            fastNode = fastNode->next;
        }
         //  当fastNode 到达末尾指针时,  slowNode  到达了 删除节点的前一个节点;

        ListNode* tmpNode;
        tmpNode = slowNode->next;
        slowNode->next = slowNode->next->next;

        delete tmpNode;
        return dummyHead->next;

    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值