算法修炼Day04|● 24. 两两交换链表中的节点 ● 19.删除链表的倒数第N个节点 ● 面试题 02.07. 链表相交 ● 142.环形链表II

68 阅读2分钟

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

1.思路

设置虚拟头节点,第一个节点、第二个节点、临时节点,终止条件的设置,指针指向比较绕,遵循从前往后的指向即可...

2.代码实现
class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode cur = dummyHead;
        ListNode temp;
        ListNode firNode;
        ListNode secNode;
        while (cur.next != null && cur.next.next != null) {
            firNode = cur.next;
            secNode = cur.next.next;
            temp = cur.next.next.next;
            cur.next = secNode;
            secNode.next = firNode;
            firNode.next = temp;
            cur = firNode;
        }
        return dummyHead.next;
    }
}
3.复杂度分析

时间复杂度:O(n).

空间复杂度:O(1).

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

1.思路

双指针法:设置虚拟头节点,快慢指针,快指针先行n步,依次循环遍历直到快指针下一节点为空,改变慢指针指向,返回虚拟头节点.next

2.代码实现

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummyHead = new ListNode(0);
        dummyHead.next = head;

        ListNode slowNode = dummyHead;
        ListNode fastNode = dummyHead;

        for (int i = 0; i < n; i++) {
            fastNode = fastNode.next;
        }
        while (fastNode.next != null) {
            fastNode = fastNode.next;
            slowNode = slowNode.next;
        }
        slowNode.next = slowNode.next.next;
        return dummyHead.next;
    }
}
3.复杂度分析

时间复杂度:O(n).

空间复杂度:O(1).

LeetCode: 面试题 02.07.链表相交

1.思路

分别遍历计算两个链表长度,比较置换A为较大值,虚拟节点复位,尾部对其,判空遍历,返回即可

2.代码实现
class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode curA = headA;
        ListNode curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != null) {
            lenA++;
            curA = curA.next;
        }
        while (curB != null) {
            lenB++;
            curB = curB.next;
        }
        // 关键的复位
        curA = headA;
        curB = headB;
        // 长度和节点头均交换
        if (lenB > lenA) {
            int tmpLen = lenA;
            lenA = lenB;
            lenB = tmpLen;
            ListNode tempNode = curA;
            curA = curB;
            curB = tempNode;
        }
        int diff = lenA - lenB;
        while (diff-- > 0) {
            curA = curA.next;
        }
        while (curA != null) {
            if (curA == curB) {
                return curA;
            }
            curA = curA.next;
            curB = curB.next;
        }
        return null;
    }
}
3.复杂度分析

时间复杂度:O(n).

空间复杂度:O(1).

LeetCode: 142.环形链表II

1.思路

快慢指针(双指针法),快指针每次走两步,慢指针每次走一步,如果两者相同,则一定存在环,同时需要公式推理出x = z,快指针从相遇节点,慢指针从head节点开始,两节点同时遍历,相遇(相等)的位置就是环的入口。

2.代码实现
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                ListNode index1 = fast; // 关键的两步:x = z
                ListNode index2 = head; // 慢节点复位到head
                while (index1 != index2) {
                    index1 = index1.next;
                    index2 = index2.next;
                }
                return index1;
            }
        }
        return null;
    }
}
3.复杂度分析

时间复杂度:O(n).

空间复杂度:O(1).