• [LeetCode]90. Reverse Linked List II链表局部反转


    Reverse a linked list from position m to n. Do it in-place and in one-pass.

    For example:
    Given 1->2->3->4->5->NULLm = 2 and n = 4,

    return 1->4->3->2->5->NULL.

    Note:
    Given mn satisfy the following condition:
    1 ≤ m ≤ n ≤ length of list.

    Subscribe to see which companies asked this question

     
    解法:和题目Reverse Linked List反转链表类似,不过这次要求反转链表中的指定一段,并且要求只能遍历一趟链表,且必须做到in-place。因此我们先找到需要反转的第一个节点的前一个节点prev,然后调用reverList来反转后面需要反转的部分,并返回头节点node,再将prev和node链接起来prev->next=node。注意到reverseList函数需要在Reverse Linked List反转链表的基础上稍微修改:反转了指定部分后,还需要将这部分与它后面没有反转的部分连起来。
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* reverseBetween(ListNode* head, int m, int n) {
            if (head == NULL || head->next == NULL || m == n) return head;
            ListNode* help = new ListNode(0);
            help->next = head;
            ListNode* prev = help;
            for (int i = 0; i < m - 1; ++i) // 找到反转的头节点的前一个节点
                prev = prev->next;
            ListNode* node = reverseList(prev->next, n - m); // 局部反转
            prev->next = node; // 前后部分链接起来
            return help->next;
        }
    private:
        ListNode* reverseList(ListNode* head, const int length) { // length为反转次数
            ListNode* rHead = NULL;
            ListNode *prev = head, *curr = prev->next, *next = curr->next;
            for (int i = 0; i < length; ++i) {
                if (i == length - 1) { // 最后一次反转
                    head->next = next; // 链接上前面的反转部分和后面的未反转部分
                    curr->next = prev; // 反转最后一个指针
                    rHead = curr;
                    break;
                }
                else {
                    curr->next = prev; // 反转一个指针
                    prev = curr; // 所有指针前移一个节点
                    curr = next;
                    next = next->next;
                }
            }
            return rHead;
        }
    };

    或者用一个函数搞定:

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* reverseBetween(ListNode* head, int m, int n) {
            if (head == NULL || head->next == NULL || m == n) return head;
            ListNode* help = new ListNode(0);
            help->next = head;
            ListNode* prev = help;
            for (int i = 0; i < m - 1; ++i)
                prev = prev->next;
            ListNode *curr = prev->next, *next = curr->next, *temp = curr, *last = NULL; // temp记录第一个反转节点,方便后面链接上最后部分节点
            for (int i = m; i < n; ++i) {
                last = next->next;
                next->next = curr;
                curr = next;
                next = last;
            }
            prev->next = curr; // 第一个未反转节点链接反转后新的头部
            temp->next = last; // 第一个反转节点链接最后一段未反转节点
            return help->next;
        }
    };
  • 相关阅读:
    tar命令解压jdk.tar.gz包 报错 gzip: stdin: not in gzip format
    CentOS6.5安装完没有网络的解决办法
    UML在需求分析阶段的应用
    UML
    UML在软件开发中各个阶段的作用和意义
    Maven那点事儿(Eclipse版)
    eclipse和myeclipse的下载地址
    div的作用
    c:if标签数据回显判断是否选中
    《Hadoop》对于高级编程Hadoop实现构建企业级安全解决方案
  • 原文地址:https://www.cnblogs.com/aprilcheny/p/4971048.html
Copyright © 2020-2023  润新知