zoukankan      html  css  js  c++  java
  • LintCode | 翻转链表II

    http://www.lintcode.com/zh-cn/problem/reverse-linked-list-ii/#

    http://www.lintcode.com/zh-cn/problem/reverse-linked-list-ii/#

    思路1:两次遍历,第一次遍历保存下m到n节点的数据;第二次遍历修改m到n节点的数据(逆着替换)。需要额外O(n)的空间。

    C++代码:

    class Solution {
    public:
        /**
         * @param head: The head of linked list.
         * @param m: The start position need to reverse.
         * @param n: The end position need to reverse.
         * @return: The new head of partial reversed linked list.
         */
        ListNode *reverseBetween(ListNode *head, int m, int n) {
            if (m >= n || head == NULL) {
                return head;
            }
            ListNode *cur = head;
            vector<int> helper(n-m+1);
            int cnt = 0, k = 0;
            while (cur != NULL) {
                cnt += 1;
                if (cnt >= m && cnt <= n) {
                    helper[k++] = cur->val;
                }
                cur = cur->next;
            }
    
            cur = head; cnt = 0;
            while (cur != NULL) {
                cnt += 1;
                if (cnt >= m && cnt <= n) {
                    cur->val = helper[--k];
                }
                cur = cur->next;
            }
    
            return head;
        }
    };
    

    思路2:in-place翻转。首先找到所制定的区间(端点),然后翻转区间,最后实施重连。不需要额外的空间。

    1. 创建dummy node,记下head;提醒一下,如果是C++,为了避免内存泄漏,创建dummy node时最好不要用ListNode *dummy = new ListNode(0),而是创建结构体:ListNode dummy(0),最后通过dummy.next返回。
    2. 通过一次遍历,找到第m个节点mth,第m个节点的前一个节点mth_prev,第n个节点,第n个节点的后一个节点nth_next
    3. 翻转指定区间的链表段(同翻转整个链表的方法)。一种方法是,先nth->next=NULL,然后调用Reverse Linked List的方法,输入为mth
    4. 重新连接链表。这时指定区间的链表已经反向,把mth_prevnth相连,mthnth_next相连。

    C++代码:

    class Solution {
    public:
        /**
         * @param head: The head of linked list.
         * @param m: The start position need to reverse.
         * @param n: The end position need to reverse.
         * @return: The new head of partial reversed linked list.
         */
        ListNode *reverseBetween(ListNode *head, int m, int n) {
            if (!head->next) return head;
            
            ListNode dummy(0); dummy.next = head;
            ListNode *mth, *nth, *mth_prev = &dummy, *nth_next;
            for (int i = 1; i < n; ++i) {
                if (i == m - 1) mth_prev = head;
                head = head->next;
            }
            mth = mth_prev->next;
            nth = head;
            nth_next = nth->next;
            
            nth->next = NULL;
            reverse_list(mth);
            mth_prev->next = nth;
            mth->next = nth_next;
            
            return dummy.next;
        }
        
        void *reverse_list(ListNode *head) {
            ListNode *prev = NULL;
            while (head) {
                ListNode *next = head->next;
                head->next = prev;
                prev = head;
                head = next;
            }
        }
    };
    
  • 相关阅读:
    ElasticSearch大数据分布式弹性搜索引擎使用—从0到1
    使用Fiddler搭建手机调试环境(我做得项目是调试微信的公众号)
    Ajax的三种实现及JSON解析
    jquery ajax调用返回json格式数据处理
    jsp页面格式化数字或时间
    java组装json和提取一个json的例子
    span的onclick事件
    Android Studio创建库项目及引用
    xmlns:android="http://schemas.android.com/apk/res/android的作用是
    Android中attrs.xml文件的使用详解
  • 原文地址:https://www.cnblogs.com/ilovezyg/p/6379965.html
Copyright © 2011-2022 走看看