代码随想录算法训练营第4天| 24. 两两交换链表中的节点, 19.删除链表的倒数第N个节点, 面试题 02.07. 链表相交, 142.环形链表II

81 阅读2分钟

代码随想录算法训练营第4天| 24. 两两交换链表中的节点, 19.删除链表的倒数第N个节点, 面试题 02.07. 链表相交, 142.环形链表II

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

自己看到题目的第一想法

Only deal with two nodes at a time, and then move forward two nodes. The difficult part is just pointer manipulation.

class Solution {
    public ListNode swapPairs(ListNode head) {        
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode ans = dummyHead;
        while(dummyHead != null && dummyHead.next != null && dummyHead.next.next != null) {
            ListNode first = dummyHead.next;
            ListNode second = dummyHead.next.next;
            ListNode secondNext = second.next;
            second.next = first;
            first.next = secondNext;
            dummyHead.next = second;
            dummyHead = first;
        }
        
        return ans.next;
    }
}

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

自己看到题目的第一想法

Since I need to do this question in one pass, I cannot calculate the length of the linkedlist in one pass first and then use this information to find the last n node. The only way to deal with this is use one fast pointer and one slow pointer.

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

面试题 02.07. 链表相交

自己看到题目的第一想法

If there is an intersection, the position of the intersection must be the same from the last node. So if I make sure that both start at the same length and move one step forward each time, they eventually intersect.

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode dA = headA;
        ListNode dB = headB;
        ListNode sA = headA;
        ListNode sB = headB;
        while (dA != null && dB != null) {
            dA = dA.next;
            dB = dB.next;
        }
        while (dA != null) {
            sA = sA.next;
            dA = dA.next;
        }
        while (dB != null) {
            sB = sB.next;
            dB = dB.next;
        }
        while (sA != null) {
            if (sA == sB) {
                return sA;
            }
            sA = sA.next;
            sB = sB.next;
        }
        return null;
    }
}

142.环形链表II

自己看到题目的第一想法

Do not know how to do. I know I need to use fast and slow pointer and find the intersection. But I do not know how to find the start of the cycle.

看完代码随想录之后的想法

There are some math trick here. I do not know how to prove it. But I can understand it. The simple idea is after the interaction node is found, start from both head and the interaction node, they will meet at the start of the cycle.

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null || head.next == null) {
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;

        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (fast == slow) {
                ListNode interaction = fast;
                ListNode start = head;
                while (interaction != start) {
                    interaction = interaction.next;
                    start = start.next;
                }
                return interaction;
            }
        }

        return null;
    }
}