您的位置:首页 > 其它

【算法总结】LinkedList 链表问题

2016-02-24 15:08 363 查看
描述:
链表问题主要是针对链表的操作,主要是链表的merge, reverse, insert/delete/in-place, Fast & Slow pointer 的操作组合起来使用的各种变形题。链表分为单向链表和双向链表(double linkedList).
例题:
Reverse:
Reverse
Linked List II

Reverse Nodes in k-Group

Merge:
Merge
k Sorted Lists

Merge Two Sorted Lists

Fast & Slow pointer
Linked
List Cycle

Reorder List

Insert/Delete/Swap/In-place
Insertion
Sort List

Remove
Duplicates from Sorted List II

综合使用 (merge sort):
Merge
k Sorted Lists

Reverse Nodes in k-Group

解决方法 & 复杂度 & 代码:
Dummy node: 

Dummy node一般是new node(0), dummy 指向第一个node, 这样无论第一个Node怎样变化,只要返回dummy的下一个就可以了。

Node dummy = new Node(0);
dummy.next = head;


Reverse:

做reverse操作的时候,是把下一个指针指向当前,一直到最后。时间:O(n) , 空间:O(1)
                   


public ListNode reverse(ListNode head){
ListNode newHead = null;
while(head != null){
ListNode next = head.next;
head.next = newHead;
newHead = head;
head = next;
}
return newHead;
}


Merge & Divide:

new一个新的head 作为一个list, 按照特定条件将两个List的node一个个append到新的head上。可以见下代码中的mergeList()方法。时间O(n), 空间O(1)

Fast & Slow pointer

一个快指针,一个慢指针,从头出发,快指针如果两倍速度走,等快指针到结束点时,慢指针到终点。往往用来找中点,也可以找1/3, 1/4点等。

ListNode fast = head;
ListNode slow = head;
while(fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
//slow 为后一半list的头
ListNode mid = slow.next;


Merge k sorted list (merge sort)

每两个list合并为一个List, 再与其他合并后的List再合并。

              




public class Solution {
/**
* @param lists: a list of ListNode
* @return: The head of one sorted list.
*/
public ListNode mergeKLists(List<ListNode> lists) {
// write your code here
if(lists==null || lists.size()==0){
return null;
}
return mergeLists(lists, 0, lists.size()-1);

}
private ListNode mergeLists(List<ListNode> lists, int l, int r){
if(l==r){
return lists.get(l);
}
int m = (l+r)/2;
ListNode left = mergeLists(lists, l, m);
ListNode right = mergeLists(lists, m+1, r);
return merge(left, right);
}
private ListNode merge(ListNode left, ListNode right){
ListNode dummy = new ListNode(0);
ListNode pre = dummy;
while(left!=null && right!=null){
if(left.val<right.val){
pre.next = left;
left = left.next;
}else{
pre.next = right;
right = right.next;
}
pre = pre.next;
}
if(left!=null){
pre.next = left;
}
if(right !=null){
pre.next = right;
}
return dummy.next;
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息