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

61 阅读1分钟

今天还是链表专题,基本都是双指针问题

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) {
        if(head == null || head.next == null)return head;
        ListNode firstNode = null;
        ListNode secondNode = null;
        ListNode dummyH = new ListNode(-1);
        dummyH.next = head;
        ListNode cur = dummyH;
        while(cur.next != null && cur.next.next != null) {
            ListNode tmp = cur.next.next.next;
            firstNode = cur.next;
            secondNode = cur.next.next;
            cur.next = secondNode;
            secondNode.next = firstNode;
            firstNode.next = tmp;
            cur = firstNode;
        }
        return dummyH.next;
    }
}

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

这道题需要定位到被删除节点的前一个节点

/**
 * 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 removeNthFromEnd(ListNode head, int n) {
        ListNode fast = head;
        ListNode slow = head;
        while(n > 0) {
            n--;
            fast = fast.next;
        } 
        if(fast == null)return head.next;
        while(fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;
        return head;
    }
}

面试题 02.07. 链表相交

注意值相同不等于相交的入口

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode nodeA = headA, nodeB = headB;
        while(nodeA != nodeB) {
            nodeA = nodeA == null?headB:nodeA.next;
            nodeB = nodeB == null?headA:nodeB.next;
        }
        return nodeA;
    }
}

142. 环形链表 II

这是个数学题

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    //总共a+b个节点
    //f = 2s f = s + nb => s = nb, f = 2nb
    //走到链表入口的节点时的步数为k = a+nb 
    //所以从head出发,和slow一起走,会在环的入口相遇
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head, slow = head;
        while(true) {
            if(fast == null || fast.next == null)return null;
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow)break;
        }
        fast = head;
        while(fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}