• leetcode 143. 重排链表 做题笔记


    题目:

    给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
    将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…

    你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

    示例 1:

    给定链表 1->2->3->4, 重新排列为 1->4->2->3.
    示例 2:

    给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.

    思路与算法:

    寻找链表中点 + 链表逆序 + 合并链表

    注意到目标链表即为将原链表的左半端和反转后的右半端合并后的结果。

    这样我们的任务即可划分为三步:

    找到原链表的中点(参考「876. 链表的中间结点」)。

    我们可以使用快慢指针来 O(N)O(N) 地找到链表的中间节点。
    将原链表的右半端反转(参考「206. 反转链表」)。

    我们可以使用迭代法实现链表的反转。
    将原链表的两端合并。

    因为两链表长度相差不超过 11,因此直接合并即可。

    复杂度分析

    时间复杂度:O(N)O(N),其中 NN 是链表中的节点数。

    空间复杂度:O(1)O(1)。

    代码:

    class Solution {
        public void reorderList(ListNode head) {
            if (head == null) {
                return;
            }
            ListNode mid = middleNode(head);
            ListNode l1 = head;
            ListNode l2 = mid.next;
            mid.next = null;
            l2 = reverseList(l2);
            mergeList(l1, l2);
        }
    
        public ListNode middleNode(ListNode head) {
            ListNode slow = head;
            ListNode fast = head;
            while (fast.next != null && fast.next.next != null) {
                slow = slow.next;
                fast = fast.next.next;
            }
            return slow;
        }
    
        public ListNode reverseList(ListNode head) {
            ListNode prev = null;
            ListNode curr = head;
            while (curr != null) {
                ListNode nextTemp = curr.next;
                curr.next = prev;
                prev = curr;
                curr = nextTemp;
            }
            return prev;
        }
    
        public void mergeList(ListNode l1, ListNode l2) {
            ListNode l1_tmp;
            ListNode l2_tmp;
            while (l1 != null && l2 != null) {
                l1_tmp = l1.next;
                l2_tmp = l2.next;
    
                l1.next = l2;
                l1 = l1_tmp;
    
                l2.next = l1;
                l2 = l2_tmp;
            }
        }
    }
    
  • 相关阅读:
    为什么叫Windows 7 ?
    关于多线程生命周期原理
    关于浏览器创建XMLHttpRequest对象
    关于ajax异步加载XML例子
    关于多线程简单原理
    指针和指针的引用
    linux学习点滴
    GCC,GDB,Makefile
    妙语集锦
    uc/os内存管理的理解
  • 原文地址:https://www.cnblogs.com/nmydt/p/14256387.html
Copyright © 2020-2023  润新知