• 链表(二)


    两个链表的交叉

    合并两个排序的链表

    链表插入排序

    链表排序(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;
    }
  • 相关阅读:
    P1182 数列分段 Section II 题解
    P3853 路标设置题解
    二分模板
    P2678 跳石头题解
    P2440 木材加工题解
    P1024 一元三次方程求解题解
    快速下载vscode的方法
    P1824 进击的奶牛题解
    P1873 砍树题解
    用户登录之asp.net cookie的写入、读取与操作
  • 原文地址:https://www.cnblogs.com/hesier/p/5588027.html
Copyright © 2020-2023  润新知