程式碼隨想錄演算法訓練營第4天 | 連結串列兩兩交換、刪除倒N、連結串列相交、環形連結串列

hailicy發表於2024-07-06

2024年7月6日

兩兩交換連結串列元素

繼續用虛擬頭節點,多建立幾個記錄指標。

題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){
            return null;
        }
        if(head.next==null){
            return head;
        }
        ListNode nextSpan = head.next.next;
        ListNode vir = new ListNode();
        vir.next = head;
        ListNode before = vir;
        while(true){
            ListNode cur1 = before.next;
            ListNode cur2 = cur1.next;
            before.next = cur2;
            cur2.next = cur1;
            cur1.next = nextSpan;
            before = cur1;
            cur1 = before.next;
            if(cur1==null||cur1.next==null){
                break;
            }
            cur2 = cur1.next;
            nextSpan = cur2.next;
        }
        return vir.next;
    }
}

題19. 刪除連結串列的倒數第n個節點

雙指標法
第二個指標先移動n+1個,當到末尾時,第一個指標的下一個就刪除。

/**
 * 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 vir = new ListNode();
        vir.next = head;
        ListNode fast = vir;
        ListNode slow = vir;
        for(int i=0;i<=n;i++){
            fast = fast.next;
        }
        while(fast!=null){
            slow = slow.next;
            fast = fast.next;
        }
        slow.next = slow.next.next;
        return vir.next;
    }
}

面試題 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) {
        if(headA==null||headB==null){
            return null;
        }
        ListNode p1 = headA,p2=headB;
        int a=1,b=1;
        while(p1.next!=null){
            p1 = p1.next;
            a+=1;
        }
        while(p2.next!=null){
            p2=p2.next;
            b+=1;
        }
        p1 = headA;
        p2 = headB;
        int cha = Math.abs(a-b);
        if(a>b){
            for(int i=0;i<cha;i++){
                 headA = headA.next;
            }
        }else{
            for(int i=0;i<cha;i++){
                 headB = headB.next;
            }
        }
        p1 = headA;
        p2 = headB;
        while(p1!=null || p2!=null){
            if(p1==p2){
                return p1;
            }else{
                p1 = p1.next;
                p2 = p2.next;
            }
        }
        return null;
    }
}

環形連結串列

不需要虛擬頭節點,快慢指標,相交之後,從相交點和head到入環位置的距離相同。

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head==null){
            return null;
        }
        ListNode fast=head,slow=head;
        do{
            fast=fast.next;
            if(fast==null){
                return null;
            }
            fast = fast.next;
            slow = slow.next;
            if(fast==null){
                return null;
            }
        }while(fast!=slow);
        fast = head;
        while(fast!=slow){
            fast = fast.next;
            slow = slow.next;
        }
        return fast;
    }
}

相關文章