1. 程式人生 > 其它 >連結串列(2)——中等難度

連結串列(2)——中等難度

技術標籤:牛客演算法篇-高頻TOP200連結串列java演算法

連結串列—中等難度(java實現)

連結串列中環的入口節點

題目描述
對於一個給定的連結串列,返回環的入口節點,如果沒有環,返回null
拓展:
你能給出不利用額外空間的解法麼?

牛客題解圖片
(圖源牛客LPL006題解)

/**
 * 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) { ListNode fast = head; ListNode slow = head; //設在進入環前路程為a,二指標在距環起點為b位置相遇,環總長(b+c) //即慢指標行 a+b , 快指標行a+b+n(b+c) //快指標速度為慢指標2倍,則 2*(a+b)=a+b+n*(b+c) //推出 a = (n-1)(b+c) + c //此時將速度相同的兩個指標分別放在開頭和環相遇位置,二者相遇在環起點
while(fast != null && fast.next != null){ fast = fast.next.next; slow = slow.next; if(fast == slow){ ListNode tmp = head; while(tmp != slow){ tmp = tmp.next; slow = slow.next;
} return slow; } } return null; } }

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

題目描述
給定一個連結串列,刪除連結串列的倒數第n個節點並返回連結串列的頭指標
例如,
給出的連結串列為:1->2->3->4->5, n= 2.
刪除了連結串列的倒數第n個節點之後,連結串列變為1->2->3->5.

備註:
題目保證n一定是有效的
請給出請給出時間複雜度為\ O(n) O(n)的演算法

題目已知給出的n一定是有效的,所以無需再考慮n小於0或者大於連結串列長度的情況

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode類 
     * @param n int整型 
     * @return ListNode類
     */
    public ListNode removeNthFromEnd (ListNode head, int n) {
        // write code here
        
        ListNode fast = head;
        ListNode slow = head;
        
        for(int i = 0; i < n; i++)
            fast = fast.next;
        
        //若n等於連結串列的長度,則直接返回去掉頭結點的連結串列
        if(fast == null)
            return head.next;
        
        while(fast.next != null){
            fast = fast.next;
            slow = slow.next;
        }
        //1 2 3 4 5 6 7   
        slow.next = slow.next.next;
        
        return head;
        
    }
}

刪除有序連結串列中重複出現的元素

題目描述
給出一個升序排序的連結串列,刪除連結串列中的所有重複出現的元素,只保留原連結串列中只出現一次的元素。
例如:
給出的連結串列為1→2→3→3→4→4→5, 返回1→2→5.
給出的連結串列為1→1→1→2→3, 返回2→3.

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode類 
     * @return ListNode類
     */
    public ListNode deleteDuplicates (ListNode head) {
        // write code here
        
        ListNode res = new ListNode(0);
        res.next = head;
        
        ListNode pre = res;
        ListNode cur = head;
       
        
        while(cur != null && cur.next != null){
            if(cur.val != cur.next.val)
                pre = cur;
            else{
                while(cur.next != null && cur.val == cur.next.val)
                    cur = cur.next;
                pre.next = cur.next;
            }
            
            cur = cur.next;
        
        }
        
        return res.next;
    }
}

連結串列的奇偶重排

題目描述
給定一個單鏈表,請設定一個函式,講連結串列的奇數位節點和偶數位節點分別放在一起,重排後輸出。
注意是節點的編號而非節點的數值。

示例1
輸入:{1,2,3,4,5,6}
返回值:{1,3,5,2,4,6}

示例2
輸入:{1,4,6,3,7}
返回值:{1,6,7,4,3}

說明:奇數節點有1,6,7,偶數節點有4,3。重排後為1,6,7,4,3

備註:連結串列長度不大於200000。每個數範圍均在int內。

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 程式碼中的類名、方法名、引數名已經指定,請勿修改,直接返回方法規定的值即可
     * 
     * @param head ListNode類 
     * @return ListNode類
     */
    public ListNode oddEvenList (ListNode head) {
        // write code here
       if(head == null || head.next == null)
           return head;
        ListNode evenhead = head.next;
        ListNode odd = head;
        ListNode even = head.next;
        
        int i = 1;
        
        while(even != null && even.next != null){
            odd.next = even.next;
            odd = odd.next;
            even.next = odd.next;
            even = even.next;
        }
        //奇數鏈與偶數鏈相連
        odd.next = evenhead;
        return head;
       
    }
}

劃分連結串列

題目描述
給出一個連結串列和一個值 ,以 為參照將連結串列劃分成兩部分,使所有小於 的節點都位於大於或等於 的節點之前。
兩個部分之內的節點之間要保持的原始相對順序。
例如:
給出1→4→3→2→5→2 和x=3,
返回 1→2→2→4→3→5.

示例1
輸入:{1,4,3,2,5,2},3
返回值:{1,2,2,4,3,5}

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode類 
     * @param x int整型 
     * @return ListNode類
     */
    public ListNode partition (ListNode head, int x) {
        // write code here
        if(head == null)
            return null;
        ListNode res1 = new ListNode(0);
        ListNode res2 = new ListNode(0);
        ListNode left = res1;
        ListNode right = res2;
        
        while(head != null){
            if(head.val < x){
                 left.next = head;
                left = left.next;
            }
            else{
                right.next = head;
                right = right.next;
            }
            
            head =head.next;
        }
        
        right.next = null;
        left.next = res2.next;
        return res1.next;
      
    }
}