[刷题记录Day4]Leetcode链表专题

No.1

题目

两两交换链表中的节点

思路

  • 模拟类型题目
  • 两个节点前后交换,同时记住原来的下一个节点
  • 虚拟头节点

代码

public ListNode swapPairs(ListNode head) {
	ListNode dummyHead = new ListNode(-1, head);
	ListNode cur = dummyHead;
	while (cur.next != null && cur.next.next != null) {
		ListNode firstNode = cur.next;
		ListNode secondNode = firstNode.next;
		ListNode temp = secondNode.next;
		// swap
		cur.next = secondNode;
		secondNode.next = firstNode;
		firstNode.next = temp;
		// next round
		cur = firstNode;
	}
	return dummyHead.next;
}

No.2

题目

删除链表的倒数第 N 个结点

思路

  • 快慢指针,让快指针领先N个节点走,随后保持快慢指针的差距为N,等快指针指向null,慢指针即指向倒数第N个节点
  • 实际处理中,拿到慢指针的上一个节点比较好做删除操作,所以让快指针领先N+1步比较方便
  • 虚拟头节点

代码

public ListNode removeNthFromEnd(ListNode head, int n) {  
    ListNode dummyHead = new ListNode(-1, head);  
    ListNode slow = dummyHead, fast = dummyHead;  
    for (int i = 0; i < n + 1; i++) {  
        fast = fast.next;  
    }  
    while (fast != null) {  
        slow = slow.next;  
        fast = fast.next;  
    }  
    // 结束while循环的时候,就是找到了被删除节点的上一个节点  
    slow.next = slow.next.next;  
    return dummyHead.next;  
}

No.3

题目

面试题 02.07. 链表相交

思路

  • 分别计算长度
  • 从后续长度相等地方开始找

代码

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {  
    int A_count = 0, B_count = 0;  
    ListNode A_cur = headA, B_cur = headB;  
    while (A_cur != null) {  
        A_cur = A_cur.next;  
        A_count++;  
    }  
    while (B_cur != null) {  
        B_cur = B_cur.next;  
        B_count++;  
    }  
    A_cur = headA;  
    B_cur = headB;  
    // 让A指向最长的链表  
    if (A_count < B_count) {  
        int temp_count = A_count;  
        A_count = B_count;  
        B_count = temp_count;  
        ListNode temp_node = A_cur;  
        A_cur = B_cur;  
        B_cur = temp_node;  
    }  
    for (int i = 0; i < (A_count - B_count); i++) {  
        A_cur = A_cur.next;  
    }  
    while (A_cur != null && B_cur != null) {  
        if (A_cur == B_cur)  
            return A_cur;  
        A_cur = A_cur.next;  
        B_cur = B_cur.next;  
    }  
    return null;  
}

No.4

题目

环形链表 II

思路

  • 快慢双指针
  • while循环:有环则寻找入口,无环则结束循环,返回null

代码

public ListNode detectCycle(ListNode head) {  
    ListNode slow = head, fast = head; // 初始化 speed(fast) = 2 * speed(slow)  
    while (fast != null && fast.next != null) { // fast步长为2,保证不会访问空指针  
        slow = slow.next;  
        fast = fast.next.next;  
        if (slow == fast) { // 有环,找到相遇点  
            ListNode p1 = slow;  
            ListNode p2 = head;  
            // 推论:2个节点,一个从开头出发,一个从meet出发,以相同速度前进,再相遇就是环入口  
            while (p1 != p2) {  
                p1 = p1.next;  
                p2 = p2.next;  
            }  
            return p1;  
        }  
    }  
    return null; // 有null指针,无环  
}
posted @ 2023-07-19 21:01  喜欢毛绒绒的番茄子  阅读(14)  评论(0)    收藏  举报