刷题日记04 | 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、02.07. 链表相交、142.环形链表II

61 阅读1分钟

刷题日记04

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

有点复杂的链表题,一开始想得是用三个指针,但其实是要定义三个临时变量、一个虚头节点和一个cur节点遍历就好操作了。链表的题做多了就感觉有思路了,还是多加练习吧。

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummyHead = new ListNode(0);
        dummyHead.next = head;
        ListNode cur = dummyHead;
        ListNode first;
        ListNode second;
        ListNode temp;
        while(cur.next != null && cur.next.next != null){
            first = cur.next;
            second = cur.next.next;
            temp = cur.next.next.next;
            cur.next = second;
            second.next = first;
            first.next = temp;
            cur = first;
        }
        return dummyHead.next;
    }
}

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

这道题是双指针法的小trick,找到倒数第n个节点。记住了就好!

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummyHead = new ListNode(0);
        dummyHead.next = head;
        ListNode slow = dummyHead;
        ListNode fast = dummyHead;
        for(int i = 0; i < n; i++){
            fast = fast.next;
        }
        while(fast.next != null){
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;
        return dummyHead.next;
    }
}

面试题 02.07. 链表相交

也算是一个小trick,通过让curA指针先移动两个链表的长度差,使得curA和curB两个指针对齐,来比较两个链表的尾部是否相同。感觉也没什么好的思路,先记下来吧

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int lenA = 0;
        int lenB = 0;
        ListNode a = headA;
        ListNode b = headB;
        while(a != null){
            a = a.next;
            lenA++;
        }
        while(b != null){
            b = b.next;
            lenB++;
        }
        a = headA;
        b = headB;
        if (lenB > lenA) {
            int tmpLen = lenA;
            lenA = lenB;
            lenB = tmpLen;
            ListNode tmpNode = a;
            a = b;
            b = tmpNode;
        }
        int gap = lenA - lenB;
        while(gap-- > 0){
            a = a.next;
        }
        while(a != null){
            if(a == b){
                return a;
            }
            System.out.println("curA =  " + a.val);
            System.out.println("curB =  " + b.val);
            a = a.next;
            b = b.next;
        }
        return null;
    }
}

142. 环形链表 II

这道题依然是双指针的应用,比较考察数学功底。这里有两个数学结论可以直接使用

  1. 如果链表有换,fast一次走两步,slow一次走一步,双指针一定相遇。
  2. 指针相遇后,从相遇节点到环入口节点的距离 等于 头结点到环入口的距离
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(slow == fast){
                ListNode index1 = fast;
                ListNode index2 = head;
                while (index1 != index2) {
                    index1 = index1.next;
                    index2 = index2.next;
                }
                return index1;
            }
        }
        return null;
    }
}