[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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章