[US Giants] 六. Linked List

Remove Nth Node From End of List

Given a linked list, remove the nth node from the end of list and return its head.

The minimum number of nodes in list is n.

Example

Given linked list: 1->2->3->4->5->null, and n = 2.

After removing the second node from the end, the linked list becomes 1->2->3->5->null.

Challenge Can you do it without getting the length of the linked list?
思路:快慢指針,快指針先走n步,然後快慢指針一起走,快指針走到頭的時候慢指針的位置就是要刪除的結點
/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 */ 
public class Solution {
    /**
     * @param head: The first node of linked list.
     * @param n: An integer.
     * @return: The head of linked list.
     */
    ListNode removeNthFromEnd(ListNode head, int n) {
        if(head==null){
            return head;
        }
        ListNode fast=head;
        ListNode slow=head;
        
        for(int i=0;i<n;i++){           //0~n-1,走n次
            fast=fast.next;
        }
        if(fast==null){                 //如果要刪除的是從頭開始的第一個結點,也就是結尾數最後一個結點
            return head.next;           //上面的fast走n次正好走出結尾點走到null,刪除頭結點,返回head.next
        }else{                               
            while(fast.next!=null){
                slow=slow.next;
            	fast=fast.next;
            }
            slow.next=slow.next.next;
        }
        return head;
    }
}

Nth to Last Node in List

Find the nth to last element of a singly linked list. 

The minimum number of nodes in list is n.

Example

Given a List  3->2->1->5->null and n = 2, return node  whose value is 1.

思路:快慢指針,快指針先走n步,然後快慢指針同時走,快指針走到末尾時,慢指針到達所求點

/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 */ 
public class Solution {
    /**
     * @param head: The first node of linked list.
     * @param n: An integer.
     * @return: Nth to last node of a singly linked list. 
     */
    ListNode nthToLast(ListNode head, int n) {
        if(n<=0 || head==null){
            return null;
        }
        
        ListNode fast=head;
        ListNode slow=head;
        for(int i=0;i<n;i++){
            fast=fast.next;
        }
        if(fast==null){                            //如果fast==null
            return head;                           //也就是n正好等於鏈表長度,因此要返回第一個結點值,也即head
        }else{
            while(fast.next!=null){
            	fast=fast.next;
            	slow=slow.next;
	        }
        }
        return slow.next;
    }
}

/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 */ 
public class Solution {
    /**
     * @param head: The first node of linked list.
     * @param n: An integer.
     * @return: Nth to last node of a singly linked list. 
     */
    ListNode nthToLast(ListNode head, int n) {
        if(n<=0 || head==null){
            return null;
        }
        
        ListNode fast=head;
        ListNode slow=head;
        for(int i=0;i<n;i++){
            fast=fast.next;
        }
        while(fast!=null){                         //這種寫法就不用單獨考慮fast爲空的情況
            fast=fast.next;
            slow=slow.next;
        }
        return slow;
        
    }
}
/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 */ 
public class Solution {                            //方法二
    /**
     * @param head: The first node of linked list.
     * @param n: An integer.
     * @return: Nth to last node of a singly linked list. 
     */
    ListNode nthToLast(ListNode head, int n) {       
        if(n<=0 || head==null){
            return null;
        }
        
        Map<Integer,Integer> map=new HashMap<>();
        ListNode node;
        int i=1;                                   //1->2->3->4->null
        for(node=head;node!=null;node=node.next){  //i++到最後i=5
            map.put(i,node.val);
            i++;
        }
        return new ListNode(map.get(i-n));
    }
}

Reorder List

Given a singly linked list L: L0 → L1 → … → Ln-1 → Ln

reorder it to: L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → …

Example

Given 1->2->3->4->null, reorder it to 1->4->2->3->null.

Challenge Can you do this in-place without altering the nodes' values?
思路:找到鏈表中點,如果鏈表長度爲偶數,前半個是中點,如果鏈表長度是奇數,正好中間的是中點
           將中點之後的部分看做第二段鏈表,把這部分鏈表反轉
           依次取出第一段鏈表和第二段鏈表的一個結點連接起來即可(中點算作第一段鏈表的結尾)
時間:找中點O(n),反轉O(n),merge起來O(n),所以總體來說還是O(n)
空間:沒有extra space,因此是O(1)
/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 */ 
public class Solution {
    /**
     * @param head: The head of linked list.
     * @return: void
     */
    public void reorderList(ListNode head) {  
        if(head==null){
            return;
        }
        
        ListNode mid=findMiddle(head);
        ListNode head2=reverse(mid.next);
        mid.next=null;                                         //一定要將第一段鏈表的結尾賦值爲null
        ListNode head1=head;
        merge(head1,head2);
    }
    
    private ListNode merge(ListNode head1,ListNode head2){
        ListNode dummy=new ListNode(-1);
        ListNode head=dummy;
        int index=0;
        while(head1!=null && head2!=null){
            if(index%2==0){                                    //index%2的值只有0或者1兩個
                head.next=head1;                               //如果是0,就連接head1鏈表此時的頭
                head1=head1.next;
            }else{                                             //如果是1,就連接head2鏈表此時的頭
                head.next=head2;
                head2=head2.next;
            }
            head=head.next;
            index++;
        }
        if(head1!=null){
            head.next=head1;
        }
        if(head2!=null){
            head.next=head2;
        }
        return dummy.next;
    }
    
    private ListNode findMiddle(ListNode head){
        ListNode fast=head;
        ListNode slow=head;
        while(fast.next!=null && fast.next.next!=null){
            slow=slow.next;
            fast=fast.next.next;
        }
        return slow;
    }
    
    private ListNode reverse(ListNode head){
        ListNode pre=null;
        while(head!=null){
            ListNode temp=head.next;
            head.next=pre;
            pre=head;
            head=temp;
        }
        return pre;
    }
}

Convert Sorted List to Balanced BST

Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.

Example
               2
1->2->3  =>   / \
             1   3
思路:遍歷鏈表放入HashMap,找中點作爲root,再分別遞歸左右子樹,因此遞歸的出口是start>end也就是沒有結點符合條件的情況
例如:偶數個結點:1->2->3->4->null,中點是2
           奇數個結點:1->2->3->4->5->null,中點是3
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    
    public TreeNode sortedListToBST(ListNode head) {  
        if(head==null){
            return null;
        }
        Map<Integer,TreeNode> map=new HashMap<>();
        ListNode node;
        int i=0;
        for(node=head;node!=null;node=node.next){
            map.put(i,new TreeNode(node.val));
            i++;
        }
        return toBST(map,0,i-1);
    }

    private TreeNode toBST(Map<Integer,TreeNode> map,int start,int end){
        if(start>end){
            return null;
        }
        int mid=start+(end-start)/2;
        TreeNode root=map.get(mid);
        root.left=toBST(map,start,mid-1);
        root.right=toBST(map,mid+1,end);
        return root;
    }

}
方法二:中點找到後仍然參與到左子樹遞歸,因此遞歸的出口是有一個結點的情況
例如:偶數個結點:1->2->3->4->null,中點是2
           奇數個結點:1->2->3->4->5->null,中點是3
/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */ 
public class Solution {
    /**
     * @param head: The first node of linked list.
     * @return: a tree node
     */
	public TreeNode sortedListToBST(ListNode head) {
        if(head==null) {
            return null;
        }
        return toBST(head,null);
    }
    
    private TreeNode toBST(ListNode head, ListNode tail){
        if(head==tail) {                                   //只有一個結點的時候,返回null
            return null;
        }
        ListNode mid=findMid(head,tail);
        TreeNode root=new TreeNode(mid.val);
        root.left=toBST(head,mid);                         //left遞歸包含中點
        root.right=toBST(mid.next,tail);                   //right遞歸包含最後一個結點後面的null
        return root;
    }
    
    private ListNode findMid(ListNode head,ListNode tail){
        ListNode slow = head;
        ListNode fast = head; 
        while(fast.next!=tail && fast.next.next!=tail){    //每一次找中點都要調用,這裏tail不能寫成null
            fast=fast.next.next;
            slow=slow.next;
        }
        return slow;
    }
}
一道Array類似題

Convert Sorted Array to Binary Search Tree

Given a sorted (increasing order) array, Convert it to create a binary tree with minimal height.

There may exist multiple valid solutions, return any of them.

Example

Given [1,2,3,4,5,6,7], return

     4
   /   \
  2     6
 / \    / \
1   3  5   7
思路:因爲是數組,確定中點後,中點前一段對左子樹遞歸,中點後一段對右子樹遞歸
例如:[1,2,3,4],  中點爲2,前一段爲[1],後一段爲[3,4]
          [1,2,3,4,5],中點爲3,前一段爲[1,2],後一段爲[3,4]        
/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */ 
public class Solution {
    /**
     * @param A: an integer array
     * @return: a tree node
     */
    public TreeNode sortedArrayToBST(int[] A) {  
        if(A==null || A.length==0){
            return null;
        }
        return toBST(A,0,A.length-1);
    } 
    
    private TreeNode toBST(int[] A,int start,int end){
        if(start>end){
            return null;
        }
        int mid=start+(end-start)/2;
        TreeNode root=new TreeNode(A[mid]);
        root.left=toBST(A,start,mid-1);
        root.right=toBST(A,mid+1,end);
        return root;
    }
}





發佈了102 篇原創文章 · 獲贊 2 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章