代码随想录Day4

题目列表

  • 24.两交换链表中的节点(LeetCode)
  • 19.删除链表的倒数第N个节点(LeetCode)
  • 面试题 02.07. 链表相交(160)(LeetCode)
  • 142.环形链表II(LeetCode)

解题过程

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

题目描述

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

解题思路

注意事项

1.明确每一步交换后链表状态

在交换过程中因为cur.next会变,所以容易混淆,此时可以设置临时变量存储涉及到的节点。
可以在每写一个语句,都列出当前链表的状态(cur,cur.next,cur.next.next),帮助理解。
设置了虚拟头节点,循环条件可以简化为 current.next != null ,因为虚拟头节点是自己创建的,一定不为空。

2.循环条件与cur的移动

要注意题目要求是两两交换。

代码展示

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode();
        dummy.next = head;
        ListNode cur = dummy; //0
        while(cur.next != null && cur.next.next != null){
            ListNode first = cur.next; //1
            ListNode second = cur.next.next; //2
            ListNode third = cur.next.next.next; //3
            //开始时,0->1->2->3

            cur.next = second;  // 0->2->3 1->2 | first = 1 
            second.next = first; // 0->2->1 1->2 | first = 1 third = 3
            first.next = third; // 0->2->1->3

            cur = cur.next.next; 
        }
        return dummy.next;
    }
}

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

题目描述

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

解题思路

  • 如果只用一个循环,考虑到双指针,快慢指针都指向最开始的节点,快指针移动 n 次,此时从“快指针指向节点”数到“满指针指向节点”就有 n+1 个,然后两个指针同时移动直到快指针指向链表最后一个有效节点,此时慢指针指向就是倒数第 n 个节点的前一个(也就是倒数第 n + 1 个)。
  • 因为删除是需要知道前一个节点的,所以这样刚好便于操作。
  • 考虑到链表只有一个结点的情况,引入虚拟头节点统一操作。

代码展示

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode();
        dummy.next = head;
        ListNode fast = dummy;
        ListNode slow = dummy;
        while(fast.next != null && n > 0 ){
            fast = fast.next;
            n--;
        }
        while(fast.next != null){
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;
        return dummy.next;
    }
}

链表相交(160)

题目描述

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。

解题思路

看了评论区版本2的大神题解,核心在寻找不变量,假设两个链表有交点,它们相交部分有 z 个节点,链表1在交点前有 x 个节点,链表2在交点前有 y 个节点,应该如何定位交点:

  • 在x == y 的情况下,两指针移动x次就能找到相等的节点并返回。
  • 在x != y 的情况下,两个指针分别遍历两个链表,一直到短的那个遍历结束也不会相等。那如何才能保证它们移动相同次数之后刚好两指针指向交点:
    指针 a 遍历链表1移动了 x + z,再从链表2的头节点移动 y 次到相交节点,一共移动 x + z + y;
    指针 b 遍历链表2至末尾移动了 y + z, 再从链表1的头节点移动 x 次到相交节点,一共移动 y + z + x;
    a 和 b 在移动相同次数(x+y+z)的情况下找到了相交节点。
  • 考虑到无交点的情况,可以让指针移动到 null 再跳到另一个链表,经历以上过程在null相遇,最后返回null。

代码展示

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode a = headA;
        ListNode b = headB;

        while(a != b){
            if(a == null){
                a = headB; 
            }else{
                a = a.next;
            } 
            if(b == null){
                b = headA; 
            }else{
                b = b.next;
            } 
        }
        return a;
    }
}

142.环形链表II

题目描述

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

解题思路

芝士在尽力理解题解罢了(
https://programmercarl.com/0142.%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8II.html#%E6%80%9D%E8%B7%AF

代码展示

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
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 = head;
                ListNode index2 = fast;
                while(index1 != index2){
                    index1 = index1.next;
                    index2 = index2.next;
                
                }
                return index1;
            }
        }
        return null;
    }
}

参考资料

代码随想录

posted @ 2025-04-26 21:57  cbdsszycfs  阅读(428)  评论(0)    收藏  举报