6/11, LinkedList 杂题

6/11, LinkedList 杂题

最早听到这题还是夏天实习吃饭的时候,现在也不知道那哥们都在忙啥。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int lenA = 0;
        int lenB = 0;
        ListNode ptrA = headA;
        ListNode ptrB = headB;
        while(ptrA != null){
            ptrA = ptrA.next;
            lenA ++;
        }
        while(ptrB != null){
            ptrB = ptrB.next;
            lenB ++;
        }

        ptrA = headA;
        ptrB = headB;

        if(lenA > lenB){
            for(int i = 0; i < lenA - lenB; i++){
                ptrA = ptrA.next;
            }
        } else {
            for(int i = 0; i < lenB - lenA; i++){
                ptrB = ptrB.next;
            }
        }

        while(ptrA != ptrB){
            ptrA = ptrA.next;
            ptrB = ptrB.next;
        }

        return ptrA;
    }
}

O(n) 时间,O(1) 空间。好久不写链表了,感觉写的有点粗糙。。

用都指向 head 的快慢指针可以判断链表长度奇偶,最后 fast == null 的时候为偶,slow 指向后半单第一个节点;fast.next == null 的时候链表长度为奇数,slow 指向中间节点。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head == null || head.next == null) return true;

        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        if(fast == null){
            ListNode headB = reverse(slow);
            return compare(head, headB);
        } else {
            ListNode headB = slow.next;
            slow = null;
            headB = reverse(headB);
            return compare(head, headB);
        }

    }

    private boolean compare(ListNode headA, ListNode headB){
        while(headA != null && headB != null){
            if(headA.val != headB.val) return false;

            headA = headA.next;
            headB = headB.next;
        }
        return true;
    }

    private ListNode reverse(ListNode head){
        ListNode prev = null;
        while(head != null){
            ListNode next = head.next;
            head.next = prev;
            prev = head;
            head = next;
        }
        return prev;
    }
}

能这样 30秒 AC 的良心水题,已经不多了=。=

public class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        while(head != null && head.next != null){
            if(head.val == head.next.val){
                head.next = head.next.next;
            } else {
                head = head.next;
            }
        }

        return dummy.next;
    }
}

40 秒能 AC 的良心水题,也不多啊!

public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode head = dummy;

        while(l1 != null && l2 != null){
            if(l1.val < l2.val){
                head.next = l1;
                l1 = l1.next;
            } else {
                head.next = l2;
                l2 = l2.next;
            }
            head = head.next;
        }
        while(l1 != null){
            head.next = l1;
            l1 = l1.next;
            head = head.next;
        }
        while(l2 != null){
            head.next = l2;
            l2 = l2.next;
            head = head.next;
        }

        return dummy.next;
    }
}

在 LeetCode 早期年代,这样的题居然可以算成 Hard 难度。。

public class Solution {

    private class NodeComparator implements Comparator<ListNode>{
        public int compare(ListNode one, ListNode two){
            return one.val - two.val;
        }
    }
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists == null || lists.length == 0) return null;

        ListNode dummy = new ListNode(0);
        ListNode head = dummy;

        PriorityQueue<ListNode> heap = new PriorityQueue<ListNode>(new NodeComparator());
        for(ListNode node : lists){
            if(node != null) heap.offer(node);
        }

        while(!heap.isEmpty()){
            ListNode node = heap.poll();
            head.next = node;
            head = head.next;

            if(node.next != null) heap.offer(node.next);
        }

        return dummy.next;

    }
}

拼接链表,认准多个 dummy node.

public class Solution {
    public ListNode oddEvenList(ListNode head) {
        ListNode oddDummy = new ListNode(0);
        ListNode evenDummy = new ListNode(0);
        ListNode odd = oddDummy;
        ListNode even = evenDummy;

        boolean isOdd = true;
        while(head != null){
            if(!isOdd){
                even.next = head;
                even = even.next;
            } else {
                odd.next = head;
                odd = odd.next;
            }
            head = head.next;
            isOdd = !isOdd;
        }
        odd.next = evenDummy.next;
        even.next = null;

        return oddDummy.next;
    }
}

一开始想复杂了,还挑着拆成两个 list .. 其实就是注意下存中间两个 node,还有这两个 node 的 prev 与 next,循环解决就行。

public class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null) return head;
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode prev = dummy;
        while(head != null && head.next != null){
            ListNode cur1 = head;
            ListNode cur2 = head.next;
            ListNode next = head.next.next;

            prev.next = cur2;
            cur2.next = cur1;
            cur1.next = next;

            head = next;
            prev = cur1;
        }

        return dummy.next;
    }
}

Last updated