• [LeetCode] 143. Reorder List


    重排链表。题意很简单,

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

    You may not modify the values in the list's nodes, only nodes itself may be changed.

    Example 1:

    Given 1->2->3->4, reorder it to 1->4->2->3.

    Example 2:

    Given 1->2->3->4->5, reorder it to 1->5->2->4->3.

    思路也很直观,但是代码容易错,算是链表题里面的综合题吧,有链表的快慢指针fast-slow pointer,反转reverse,和merge两个链表三个技能点的考察。找快慢指针的时候记得设一个temp node,因为slow停下的地方会是second half的起点,这个temp指针会停在first half的尾部。

    时间O(n)

    空间O(1)

    JavaScript实现

     1 /**
     2  * @param {ListNode} head
     3  * @return {void} Do not return anything, modify head in-place instead.
     4  */
     5 var reorderList = function(head) {
     6     if (!head || !head.next) return;
     7     let fast = head;
     8     let slow = head;
     9     while (fast && fast.next) {
    10         fast = fast.next.next;
    11         slow = slow.next;
    12     }
    13     let second = reverseList(slow.next);
    14     slow.next = null;
    15     let first = head;
    16     while (second) {
    17         let temp = second.next;
    18         second.next = first.next;
    19         first.next = second;
    20         first = first.next.next;
    21         second = temp;
    22     }
    23 };
    24 
    25 var reverseList = function(head) {
    26     let pre = null;
    27     while (head !== null) {
    28         let next = head.next;
    29         head.next = pre;
    30         pre = head;
    31         head = next;
    32     }
    33     return pre;
    34 };

    Java实现

     1 class Solution {
     2     public void reorderList(ListNode head) {
     3         if (head == null || head.next == null) {
     4             return;
     5         }
     6         ListNode temp = null;
     7         ListNode slow = head;
     8         ListNode fast = head;
     9         ListNode l1 = head;
    10         while (fast != null && fast.next != null) {
    11             temp = slow;
    12             slow = slow.next;
    13             fast = fast.next.next;
    14         }
    15         temp.next = null;
    16         ListNode l2 = reverse(slow);
    17         merge(l1, l2);
    18     }
    19 
    20     private ListNode reverse(ListNode head) {
    21         ListNode prev = null;
    22         while (head != null) {
    23             ListNode next = head.next;
    24             head.next = prev;
    25             prev = head;
    26             head = next;
    27         }
    28         return prev;
    29     }
    30 
    31     private void merge(ListNode l1, ListNode l2) {
    32         while (l1 != l2) {
    33             ListNode n1 = l1.next;
    34             ListNode n2 = l2.next;
    35             l1.next = l2;
    36             if (n1 == null)
    37                 break;
    38             l2.next = n1;
    39             l1 = n1;
    40             l2 = n2;
    41         }
    42     }
    43 }

    另一种Java实现,把getMiddle写成一个函数,注意while循环的部分

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode() {}
     7  *     ListNode(int val) { this.val = val; }
     8  *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     9  * }
    10  */
    11 class Solution {
    12     public void reorderList(ListNode head) {
    13         // corner case
    14         if (head == null || head.next == null) {
    15             return;
    16         }
    17         // normal case
    18         ListNode middle = findMiddle(head);
    19         ListNode first = head;
    20         ListNode second = middle.next;
    21         middle.next = null;
    22         second = reverse(second);
    23         merge(first, second);
    24     }
    25 
    26     private ListNode findMiddle(ListNode head) {
    27         ListNode slow = head;
    28         ListNode fast = head;
    29         while (fast != null && fast.next != null) {
    30             slow = slow.next;
    31             fast = fast.next.next;
    32         }
    33         return slow;
    34     }
    35 
    36     private ListNode reverse(ListNode head) {
    37         ListNode pre = null;
    38         while (head != null) {
    39             ListNode next = head.next;
    40             head.next = pre;
    41             pre = head;
    42             head = next;
    43         }
    44         return pre;
    45     }
    46 
    47     private void merge(ListNode left, ListNode right) {
    48         ListNode leftTemp;
    49         ListNode rightTemp;
    50         while (left != null && right != null) {
    51             leftTemp = left.next;
    52             rightTemp = right.next;
    53             left.next = right;
    54             right.next = leftTemp;
    55             left = leftTemp;
    56             right = rightTemp;
    57         }
    58     }
    59 }

    LeetCode 题目总结

  • 相关阅读:
    Monggodb基础
    手游运营数据指标
    JSON语法
    Java中日期转换问题
    Java线程中锁的问题
    鼠标移动监听的注意事项
    链接数据库的问题
    获取显示器的宽高
    JTable的使用问题
    JScrollPane控件中添加其他控件的问题&&JScrollPane设置滚动条&&调整滚动速度
  • 原文地址:https://www.cnblogs.com/cnoodle/p/11830191.html
Copyright © 2020-2023  润新知