链表(二)

两个链表的交叉

合并两个排序的链表

链表插入排序

链表排序(O(n log n) )

删除链表中倒数第n个节点

回文链表

 

合并两个排序的链表

输入两个单调递增的链表,输出两个链表合成后的链表,合成后的链表满足单调不减规则。

public class Solution {
    // 非递归
    public ListNode Merge2(ListNode list1,ListNode list2) {
 
        ListNode dummy = new ListNode(0);
        ListNode lastNode = dummy;
         
        while(list1!=null && list2!=null){
            if(list1.val<list2.val){
                lastNode.next = list1;
                list1 = list1.next;
            }else{
                lastNode.next = list2;
                list2 = list2.next;
            }
             
            lastNode = lastNode.next;
        }
         
        if(list1!=null){
            lastNode.next = list1;
        }else{
            lastNode.next = list2;
        }
         
        return dummy.next;
    }
     
    //递归
    public ListNode Merge(ListNode list1,ListNode list2) {
        if(list1==null)
            return list2;
        if(list2==null){
            return list1;
        }
         
        ListNode mergeHead = null;
        if(list1.val < list2.val){
            mergeHead = list1;
            mergeHead.next = Merge(list1.next, list2);
        }else{
            mergeHead = list2;
            mergeHead.next = Merge(list1, list2.next);
        }
        return mergeHead;
    }
}

 

 两个链表的交叉

找到两个单链表最开始的交叉节点

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    if(headA==null || headB==null)  return null;
    if(headA==headB)  return headA;
    
    int cnt1=0, cnt2=0;
    ListNode head = headA;
    while(head!=null){
        cnt1++;
        head = head.next;
    }
    head = headB;
    while(head!=null){
        cnt2++;
        head = head.next;
    }
    
    while(cnt1>cnt2){
        headA = headA.next;
        cnt1--;
    }
    while(cnt1<cnt2){
        headB = headB.next;
        cnt2--;
    }
    
    while(headA!=headB){
        headA = headA.next;
        headB = headB.next;
    }
    return headA;
}

 

链表插入排序

public ListNode insertionSortList(ListNode head) {
    ListNode dummy = new ListNode(0);
    while (head != null) {
        ListNode node = dummy;
        while (node.next != null && node.next.val < head.val) {
            node = node.next;
        }
        ListNode temp = head.next;
        head.next = node.next;    //插入
        node.next = head;
        head = temp;    // 跳到下一个
    }

    return dummy.next;
}

 

链表排序(O(n log n) )

在 O(n log n) 时间复杂度和常数级的空间复杂度下给链表排序。

public ListNode sortList(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    ListNode slow = head, fast = head.next.next;
    while (fast != null && fast.next != null) {
        fast = fast.next.next;
        slow = slow.next;
    }
    ListNode p2 = sortList(slow.next);
    slow.next = null;
    ListNode p1 = sortList(head);
    return merge(p1, p2);
}

private ListNode merge(ListNode p1, ListNode p2) {
    ListNode p, dummy = new ListNode(0);
    p = dummy;
    while (p1 != null && p2 != null) {
        if (p1.val < p2.val) {
            p.next = p1;
            p1 = p1.next;
        } else {
            p.next = p2;
            p2 = p2.next;
        }
        p = p.next;
    }
    p.next = (p1==null?p2:p1);
    return dummy.next;
}  

 

删除链表中倒数第n个节点

给定一个链表,删除链表中倒数第n个节点,返回链表的头节点。

public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode n1 = head;
    ListNode n2 = head;
    
    ListNode dummy = new ListNode(0);
    dummy.next = n2;
    
    int i = 0;
    while(i<n){
        n1 = n1.next;
        i++;
    }
    
    while(n1.next!=null){
        n1 = n1.next;
        n2 = n2.next;
    }
    
    n2.next = n2.next.next;
    return dummy.next;
}

返回链表中倒数第k个结点

public ListNode findKthToTail(ListNode head, int k) {
    if(head==null || k<=0)
        return null;
    
    ListNode right = head;
    ListNode left = head;
    for(int i=1; i<k; i++){
        if(right.next!=null)
            right = right.next;
        else
            return null;
    }

    while(right.next!=null){
        left = left.next;
        right = right.next;
    }
    return left;
}

 

 回文链表

public boolean isPalindrome(ListNode head) {

    if(head==null) return true;
    ListNode fast = head;
    ListNode slow = head;
    
    while(fast!=null && fast.next!=null){
        fast = fast.next.next;
        slow = slow.next;
    }
    
    // when the length is odd
    if(fast!=null){
        fast = fast.next;
    }
    
    // reverse the second half
    ListNode prev = null;
    while(slow!=null){
        ListNode tmp = slow.next;
        slow.next = prev;
        prev = slow;
        slow = tmp;
    }
    
    slow = prev;
    while(slow!=null){
        if(head.val != slow.val){
            return false;
        }
        head = head.next;
        slow = slow.next;
    }
    
    return true;
}

 

posted @ 2016-06-15 16:40  Hesier  阅读(184)  评论(0编辑  收藏  举报