• [LeetCode题解]92. 反转链表 II | 一次遍历 + 反转


    解题思路

    将链表分为三部分:[0, m)[m, n](n, L],其中 L 为链表长度。

    第一步:使用虚拟头节点 dummy,用于将 head 也能参与操作;
    第二步:找到第 m-1 节点(firstHalfEnd),用于连接反转后的第二部分链表;
    第三步:遍历[m, n],进行链表反转。注意在反转前要保存待反转链表区间的第一个节点,用于连接第三部分链表;
    第四步:

    firstHalfEnd.next = pre;    // 此时的 pre 指向反转后的链表区间的第一个节点
    secondHalfEnd.next = cur;   // 此时的 cur 指向第三部分链表的第一个节点,也就是第 n+1 个节点
    

    代码

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     public int val;
     *     public ListNode next;
     *     public ListNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public ListNode ReverseBetween(ListNode head, int m, int n) {
            if(head == null || head.next == null || m == n) {
                return head;
            }
    
            ListNode dummy = new ListNode(0);
            dummy.next = head;
    
            ListNode cur = head;
            ListNode firstHalfEnd = dummy;
            for(int i = 1; i < m; i++) {
                firstHalfEnd = cur;
                cur = cur.next;
            }
    
            // 反转链表区间
            ListNode pre = null, secondHalfEnd = cur;
            for(int i = m; i <= n; i++) {
                var nextTmp = cur.next;
                cur.next = pre;
                pre = cur;
                cur = nextTmp;
            }
    
            // 此时的 cur 指向第三部分的头节点
            firstHalfEnd.next = pre;
            secondHalfEnd.next = cur;
        
            return dummy.next;
        }
    }
    

    复杂度分析

    • 时间复杂度:(O(n)),其中 (n) 是链表的长度。一次遍历,因此时间复杂度为 (O(n))
    • 空间复杂度:(O(1))
  • 相关阅读:
    算法竞赛入门经典习题2-3 韩信点兵
    ios入门之c语言篇——基本函数——5——素数判断
    ios入门之c语言篇——基本函数——4——数值交换函数
    144. Binary Tree Preorder Traversal
    143. Reorder List
    142. Linked List Cycle II
    139. Word Break
    138. Copy List with Random Pointer
    137. Single Number II
    135. Candy
  • 原文地址:https://www.cnblogs.com/liang24/p/14013564.html
Copyright © 2020-2023  润新知