代码随想录刷题day04|两两交换&删除倒N&链表相交&环形链表

文章讲述了在编程中如何正确处理链表操作,如两两交换链表节点、使用双指针法删除倒数第N个节点、链表相交以及识别环形链表。作者强调了画图理解、错误分析和关键代码片段的重要性。
摘要由CSDN通过智能技术生成


day04学习内容

day04主要内容

  • 两两交换链表中的节点
  • 删除倒数第N个节点
  • 链表相交
  • 环形链表

一、 两两交换链表中的节点

24原题链接

1.错误写法1

class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head==null){
            return null;
        }
        ListNode dummy = new ListNode(-1,head);
        ListNode cur = dummy;
        while(cur.next!=null&&cur.next.next!=null){
            ListNode tempNode1 = cur.next;
            ListNode tempNode2 = cur.next.next;
            ListNode tempNode3 = cur.next.next.next;
            cur.next = tempNode2;
            tempNode2.next = tempNode1;
            tempNode1.next = tempNode3;  
            cur = tempNode2; //注意就是这一句话写错了,为什么错了,看下面分析
        }
        return dummy.next;
    }
}

假如head = 1->2->3->4->null,代码执行到tempNode1.next = tempNode3这一步时,此时链表的变化过程如下俩图(数字就是交换的执行顺序),
第一次交换位置
cur指针的变化
因为要让cur重新指向需要交换的2个节点的前1个节点,此时节点【3】的前一个节点是【1】,所以此时cur=N1而不是cur=N2

2.正确写法1

class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head==null){
            return null;
        }
        ListNode dummy = new ListNode(-1,head);
        ListNode cur = dummy;
        while(cur.next!=null&&cur.next.next!=null){
            ListNode tempNode1 = cur.next;
            ListNode tempNode2 = cur.next.next;
            ListNode tempNode3 = cur.next.next.next;
            cur.next = tempNode2;
            tempNode2.next = tempNode1;
            tempNode1.next = tempNode3;  
            cur = tempNode1;
        }
        return dummy.next;
    }
}

2.正确写法2

`采用双指针

class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head==null){
            return null;
        }
        ListNode dummy = new ListNode(-1,head);
        ListNode cur = dummy;
        while(cur.next!=null&&cur.next.next!=null){
            ListNode tempNode1 = cur.next;
            ListNode tempNode3 = cur.next.next.next;
            cur.next = cur.next.next;
            cur.next.next = tempNode1;//注意这里不要写成cur.next.next.next了,画图理解一下就知道为什么要这么写了
            tempNode1.next = tempNode3;  
            cur = tempNode1;
        }
        return dummy.next;
    }
}

二、删除倒数第N个节点(双指针法)

19原题链接

思路:
这一题主要是想明白,怎么找到倒数第N个节点。

  1. 问题1:
    我就没想到快指针要先走N+1步,看了题解和视频才看明白的,才知道这个思路
  2. 问题2
    先让快指针走n步,不知道怎么写代码。。。离天下之大谱
  3. 问题3
    不知道怎么让fast和slow同时移动,直到fast==null终止

好家伙,很简单的一题就有三个问题了,基本等于一句都不会写。

1.正确写法1

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(-1,head);
        ListNode fast = dummy;
        ListNode slow = dummy;
        for(int i=0;i<=n;i++){
            fast = fast.next;
        }
        while(fast!=null){
            fast = fast.next;
            slow = slow.next;
        }

        slow.next= slow.next.next;
        return dummy.next;
    }
}

三、链表相交

02.07原题链接

1.正确写法-双指针

四、环形链表

142原题链接

1.思考

  • 核心思路
  •  判断是否有环:fast==slow,就说明有环
    
  •  怎么找到相遇节点:index1=index2,即从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。
    

-疑问1:在相遇节点处定义一个指针,为什么这个指针index1=fast?
解释:因为是用快指针作为桥梁的,所以肯定是fast
-疑问2:为什么index=head?

2.正确写法

public 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 (fast == slow) {// 相遇
                ListNode index1 = fast;
                ListNode index2 = head;
                while (index1 != index2) {
                    index1 = index1.next;//不要写成index1=fast.next了
                    index2 = index2.next;
                }
                return index1;
            }

        }
        return null;
    }
}

总结

1.感想

  • 俩俩交互节点和删除倒数第N个节点,很容易写着写着就把指针搞错了,建议写代码一定要画图理解
  • 环形链表代码不难,思路很难,不看题解我是完全想不到的。

2.思维导图

本文思路引用自代码随想录,感谢代码随想录作者。

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值