Day 4 | 24.两两交换链表中的节点 19.删除链表的倒数第N个节点 02.07. 链表相交 142.环形链表II

本文介绍了如何通过编程解决链表相关问题,包括两两交换链表节点、删除链表倒数第N个节点以及判断两个链表是否有环。作者详细解释了代码实现过程和解题思路,强调了处理特殊情况和优化算法的重要性。
摘要由CSDN通过智能技术生成

24.两两交换链表中的节点

我的代码:

 ListNode* swapPairs(ListNode* head) {
        if(head == nullptr) return head;
        ListNode* DummyNode = new ListNode();
        DummyNode->next = head;
        ListNode* cur = DummyNode;
        while(cur->next != nullptr && cur->next->next != nullptr){
            ListNode* tmp1 = cur->next;
            ListNode* tmp3 = cur->next->next->next;
            cur->next = cur->next->next;
            cur->next->next = tmp1;
            cur->next->next->next = tmp3;
            cur = cur->next->next; 
        }
        return DummyNode->next;
    }

做题心得和注意事项:

        首先要搞清楚要变换哪几个节点,以例子的 1234为例,设立个虚拟头结点为了不用对头结点单独处理。

        之后就是对12进行变换,对12转换成21,我们得保留在转换中会丢失的节点信息,一个就是 1,一个就是3,因为按照顺序,我们会将 虚拟头结点指向2,则原本指向1的地址就没了,1就丢失了,那么我们就需要保存1的链表信息,代码中我定义为 tmp1,此外当我们完成了 虚拟头结点->2->1,之后 3本来是接在 2后面,但是 2后面按照顺序指向了1,所以 3的地址也就丢失了,那么我们就得额外给 3节点一个指针进行保存,代码中我定义为 tm3,当这些元素都保存好后,就可以按照正常的转换一步一步赋值进行下去了。

        此外还需要注意, cur 指针的移动是移动 2格,因为是 2个2个转换,模拟一下即可明白。

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

我的代码:

 ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* cur = head;
        ListNode* DummyNode = new ListNode();
        ListNode* cur_while = DummyNode;
        DummyNode->next = head;
        int size = 0;
        while(cur != nullptr){
            size++;
            cur = cur->next;
        }
        int nums = size - n;
        while(nums--){
            cur_while = cur_while->next;
        }
        ListNode* tmp = cur_while->next;
        cur_while->next = cur_while->next->next;
        delete tmp;
        return DummyNode->next;
    }

做题心得和注意事项:

        想法思路很朴素,先记录建表的长度,再根据倒数第几个需要删除的,计算出正向遍历的次数 nums,之后就是简单的删除操作,没有其他需要注意的东西了。

 面试题 02.07. 链表相交  

我的代码:

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int A_len = 0, B_len = 0, minus;
        ListNode* LenA = headA;
        ListNode* LenB = headB;
        while(LenA != nullptr){
            A_len++;
            LenA = LenA->next;
        }
        while(LenB != nullptr){
            B_len++;
            LenB = LenB->next;
        }
        LenA = headA;
        LenB = headB;
        if(A_len > B_len){
            minus = A_len - B_len;
            while(minus--){
                LenA = LenA->next;
            }
            while(LenA != nullptr){
                if(LenA == LenB) return LenA;
                LenA = LenA->next;
                LenB = LenB->next;
            }
        }else{
            minus = B_len - A_len;
            while(minus--){
                LenB = LenB->next;
            }
            while(LenB != nullptr){
                if(LenA == LenB) return LenB;
                LenB = LenB->next;
                LenA = LenA->next;
            }
        }
       return NULL;
    }

心得:

         下面写 if 的地方还是可以优化, 可以swap()直接选择 A或者B 为最大的那个,直接进行操作。

在写 142 之前可以先写 141.环形链表 | ,有个关联关系

141.环形链表 |

后面补上

142.环形链表||

心得:

  1. 为何慢指针第一圈走不完一定会和快指针相遇? 可以认为快指针和慢指针是相对运动的,假设慢指针的速度是 1节点/秒,快指针的速度是 2节点/秒,当以慢指针为参考系的话(即慢指针静止),快指针的移动速度就是 1节点/秒,所以肯定会相遇。
  2. 为什么在第一圈就会相遇呢? 设环的长度为 L,当慢指针刚进入环时,慢指针需要走 L 步(即 L 秒)才能走完一圈,此时快指针距离慢指针的最大距离为 L-1,我们再次以慢指针为参考系,如上所说,快指针在按照1节点/秒的速度在追赶慢指针,所以肯定能在 L 秒内追赶到慢指针。
  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值