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

30 阅读2分钟

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

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummyNode = new ListNode(0);
        ListNode cur = dummyNode;
        dummyNode.next = head;
        while(cur.next != null && cur.next.next != null) {
            //保存第一个节点
            ListNode temp1 = cur.next;
            //保存第三个节点
            ListNode temp2 = cur.next.next.next;
            //让虚拟节点指向第二个节点
            cur.next = cur.next.next;
            //让第二个·节点指向第一个节点
            cur.next.next = temp1;
            //让第一个节点指向第三个节点
            temp1.next = temp2;
            //让第cur指向交换后的第二个节点
            cur = temp1;
        }
        return dummyNode.next;
    }
}

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

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummyNode = new ListNode(0);
        ListNode cur = dummyNode;
        dummyNode.next = head;
        while(cur.next != null && cur.next.next != null) {
            //保存第一个节点
            ListNode temp1 = cur.next;
            //保存第三个节点
            ListNode temp2 = cur.next.next.next;
            //让虚拟节点指向第二个节点
            cur.next = cur.next.next;
            //让第二个·节点指向第一个节点
            cur.next.next = temp1;
            //让第一个节点指向第三个节点
            temp1.next = temp2;
            //让第cur指向交换后的第二个节点
            cur = temp1;
        }
        return dummyNode.next;
    }
}

 面试题 02.07. 链表相交  

注意 数值相同,不代表指针相同。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        //记录A链表、B链表的长度
        int lenA = 0;
        int lenB = 0;
        //定义临时节点
        ListNode curA = headA;
        ListNode curB = headB;
        //求lenA
        while (headA != null) {
            lenA++;
            headA = headA.next;
        }
        //求lenB
        while (headB != null) {
            lenB++;
            headB = headB.next;
        }
        // 让B链表始终为最大长度
        if (lenA > lenB) {
            // 1. swap (lenA, lenB);
            int tmpLen = lenA;
            lenA = lenB;
            lenB = tmpLen;
            // 2. swap (curA, curB);
            ListNode tmpNode = curA;
            curA = curB;
            curB = tmpNode;
        }
        // A链表与B链表末端保持对齐
        // 让最大长度的B链表的临时节点指向与A链表平齐的第一个节点
        int gap = lenB - lenA;
        while (gap > 0) {
            curB = curB.next;
            gap--;
        }
        // 判断两个节点是否相等,相等则直接返回,否则指针向前加一
        while (curB != null) {
            if (curA == curB) {
                return curA;
            } else {
                curA = curA.next;
                curB = curB.next;
            }
        }
        return null;
    }
}

 142.环形链表II  

链表比较有难度的题目,第一次做根本没有思路,需要多花点时间理解 确定环和找环入口,建议先看视频。

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = 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;
    }
}