zoukankan      html  css  js  c++  java
  • Linked list 链表完整笔记

    Reorder List

    Given a singly linked list LL0→L1→…→Ln-1→Ln,
    reorder it to: L0→LnL1→Ln-1→L2→Ln-2→…

    You must do this in-place without altering the nodes' values.

    For example,
    Given {1,2,3,4}, reorder it to {1,4,2,3}.

     思路:

      1.找到中点

      2.把中点后的链表反转

      3.把2部分链表merge起来

      注意把middle.next = null

      

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public void reorderList(ListNode head) {
            if (head == null || head.next == null) {
                return;
            }
            ListNode mid = findMiddle(head);
            ListNode tail = reverseList(mid.next);
            //keng
            mid.next = null;
    
            combine(head, tail);
        }
        //step 1 find middle 
        private static ListNode findMiddle(ListNode head) {
            ListNode slow, fast;
            slow = head;
            fast = head;
            while (fast.next != null && fast.next.next != null) {
                slow = slow.next;
                fast = fast.next.next;
            }
            return slow;
        }
        //step 2 reverse the list after the middle node
        private static ListNode reverseList(ListNode head) {
            ListNode newHead = null;
            while (head != null) {
                ListNode temp = head.next;
                head.next = newHead;
                newHead = head;
                head = temp;
            }
            return newHead;
        
        }
        //step 3 conbine two list
        private static void combine(ListNode head, ListNode tail) {
            while (head != null && tail != null ) {
                ListNode tempHead = head.next;
                ListNode tempTail = tail.next;
                head.next = tail;
                tail.next = tempHead;
                tail = tempTail;
                head = head.next.next;
            }
        }
    }
    reorderList

    九章的代码

    在merge部分,利用的%2的方式,一次取1个点出来

    reorderList

     -----------------------------------------------------------

    sort list 

    merge sort, 用divide and conquer的方式,先把list分为左右部分,然后排序后合并

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode sortList(ListNode head) {
    11         if (head == null) {
    12             return head;
    13         }
    14         return helper(head);
    15     }
    16     private ListNode helper(ListNode head) {
    17         // step 1, divide 
    18         if (head == null || head.next == null) {
    19             return head;
    20         }
    21         //find the mid point and need to set mid.next = null!
    22         ListNode mid = findMiddle(head);
    23         ListNode right = sortList(mid.next);
    24         mid.next = null;
    25         ListNode left = sortList(head);
    26         return merge(left, right);
    27        
    28     }
    29     
    30     private ListNode merge (ListNode left, ListNode right) {
    31         // step 2 conqure 
    32         ListNode dummy = new ListNode(0);
    33         ListNode current = dummy;
    34 
    35         while (left != null || right != null) {
    36             while (left != null && right != null) {
    37                 if (left.val >= right.val) {
    38                     current.next = right;
    39                     right = right.next;
    40                 } else {
    41                     current.next = left;
    42                     left = left.next;
    43                 }
    44                 current = current.next;
    45             }
    46             if (left != null) {
    47                 current.next = left;
    48                 left = null;
    49             }
    50             if (right != null) {
    51                 current.next = right;
    52                 right = null;
    53             }
    54         }
    55         return dummy.next;
    56     }
    57     
    58     private ListNode findMiddle(ListNode head) {
    59         ListNode fast = head.next;
    60         ListNode slow = head;
    61         while (fast != null && fast.next != null) {
    62             fast = fast.next.next;
    63             slow = slow.next;
    64         }
    65         return slow;
    66     }
    67     
    68 }
    sort list (divide and conquer)

     quick sort

    sortList

     -----------------------------------------------------------

     Intersection of Two Linked Lists

    Write a program to find the node at which the intersection of two singly linked lists begins.

    For example, the following two linked lists:

    A:          a1 → a2
                       ↘
                         c1 → c2 → c3
                       ↗            
    B:     b1 → b2 → b3
    

    begin to intersect at node c1.

    双指针法:

    1. 找到两条链表的长度

    2. 长的链表先把current向前走长度差个单位

    3.两个指针一起往后走,知道相等就打断

    代码:

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    public class Solution {
        public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
            int lengthA = getLength(headA);
            int lengthB = getLength(headB);
            int dis = Math.abs(lengthA -lengthB);
            ListNode fast = lengthA >= lengthB ? headA : headB;
            ListNode slow = lengthA >= lengthB ? headB : headA;
            for (int i = 0; i < dis; i++) {
                fast = fast.next;
            }
            while (fast != null && slow != null) {
                if (fast.val == slow.val) {
                    return fast;
                }
                fast = fast.next;
                slow = slow.next;
            }
            return null;
            
        }
        private static int getLength(ListNode head) {
            int len = 0;
            while (head != null) {
                head = head.next;
                len++;
            }
            return len;
        }
    }
    getIntersectionNode
     
  • 相关阅读:
    HTML5的页面资源预加载技术(Link prefetch)加速页面加载
    正则表达式入门教程
    SQL 查询分析器操作(修改、添加、删除)表及字段等
    linux终端相关概念解释及描述
    linux系统编程--守护进程,会话,进程组,终端
    linux系统编程--信号
    linux系统编程--进程间通信
    linux系统编程--进程
    Python GUI编程(Tkinter)(一)
    C++中时间转换
  • 原文地址:https://www.cnblogs.com/jiangchen/p/5933415.html
Copyright © 2011-2022 走看看