• 【LeetCode & 剑指offer刷题】链表题1:14 反转链表 206. Reverse Linked List(系列)


    【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

    206. Reverse Linked List

    Reverse a singly linked list.
    Example:
    Input: 1->2->3->4->5->NULL
    Output: 5->4->3->2->1->NULL
    Follow up:
    A linked list can be reversed either iteratively or recursively. Could you implement both?
     
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    //迭代法
    //O(n),O(1)
    class Solution
    {
    public:
        ListNode* reverseList(ListNode* head)
        {
            if(head == nullptr) return nullptr;
           
            ListNode *pre = nullptr, *cur = head,*next; //三个指针分别保存之前,当前,下一个结点
            while(cur)
            {
                next = cur->next; //保存原链表该结点的下一个结点,以免变换指向之后无法遍历到下一个结点
                cur->next = pre; //变换指向
               
                pre = cur; //更新指针
                cur = next; //更新指针
            }
            return pre; //最后pre指向最后一个结点,cur指向null
        }
    };
     
    //递归法(不太好理解)
    /*
    O(n) O(n)(来自递归栈)
    Assume from node nk+1 to nm had been reversed and you are at node nk.
    n1 → … → nk-1 → nk → nk+1 ← … ← nm
    We want nk+1’s next node to point to nk.
    So,
    nk.next.next = nk;
    */
    class Solution
    {
    public:
        ListNode* reverseList(ListNode* head)
        {
            if(head == nullptr || head->next == nullptr) return head;
           
            ListNode* p = reverseList(head->next); //递归之后为从后往前开始转向
            head->next->next = head;
            head->next = nullptr;
            return p;
        }
    };
     
    92. Reverse Linked List II
    Reverse a linked list from position m to n. Do it in one-pass.
    Note: 1 ≤ m  n ≤ length of list.
    Example:
    Input: 1->2->3->4->5->NULL, m = 2, n = 4
    Output: 1->4->3->2->5->NULL
     
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    /*
    问题:翻转链表2(位置m~n翻转)
    方法:m~n位置处的链表进行翻转,然后连接m-1位置与n位置,m位置与n+1位置
    例:
    Input: 1 -> 2 -> 3 -> 4 -> 5 -> NULL, m = 2, n = 4
    翻转得,1 <-> 2(m) <- 3 <- 4(n)   5 -> NULL
    连接得,1 -> 4 -> 3 -> 2 -> 5 -> NULL
    */
    class Solution
    {
    public:
        ListNode* reverseBetween(ListNode* head, int m, int n)
        {
            //异常情况处理(严格来说,还需判断m,n值是否超出链表长度,题目已经有此条件)
            if(!head || !head->next || m<0 || n<0 || m>=n) return head;
          
            //prehead的应用:头结点前的结点,方便索引,方便分析(链表用1开头+prehead分析较好,序号可以与步数对应起来)
            //且指向了链表的头结点,当m=1时,原头结点被换到后面,若返回head会出错,
            //而用prehead会指向新头结点,故返回prehead.next不会出错
            ListNode prehead(0);
            prehead.next = head;
           
            ListNode* cur = &prehead;
            for(int i = 1; i <= m-1; i++)
                cur = cur->next; //最后cur处在m-1位置
           
            ListNode* pre = cur;
            ListNode* next;
            cur = cur->next; //cur处在m位置
            ListNode* prefirst = pre, *first = cur; //保存m-1位置和m位置处的结点
           
            for(int i = m; i<=n; i++) //翻转位置m~n处的链表
            {
                next = cur->next;
                cur->next = pre;
               
                pre = cur; //更新指针
                cur = next; //更新指针
            }//退出时,pren处,curn+1
           
            prefirst->next = pre; //连接m-1n位置
            first->next = cur; //连接mn+1位置
           
            return prehead.next;
        }
    };
     
     
     
     
  • 相关阅读:
    AIR 访问网络资源老提示 Unhandled ioError 错误的解决办法
    Flex组件 EWindow 和 TimerStepper
    获取Flex SDK加载进度的方法
    我的第一个ANE程序
    给flex的自定义组件分类,使自定义组件放到组件面板的不同文件夹下!
    The status code returned from the server was: 500
    如何有效编写软件的75条建议
    让上帝讲真话——谈客户访谈思路
    C#之虚函数
    向您推荐几个虚拟化技术的BLOG(5.8日增加)
  • 原文地址:https://www.cnblogs.com/wikiwen/p/10225166.html
Copyright © 2020-2023  润新知