c++实现链表反转:leetcode206题和92题

0 介绍

链表反转是一道常见的算法面试题,题意也很直白,就是让你将一个指定链表反序。Leetcode206题和92题考查了这样一道题目,下面来看一看。

1 Leetcode206题-反转链表I

该题题目描述如下:

反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

解决这样一个问题需要三个指针pre、cur、tail,以示例输入为例,我们首先将pre初始化为空指针,cur初始化为输入链表的头指针。当cur不为空指针时,我们循环的将tail设置为cur的next指针,然后将cur的next指向pre,然后将pre指向cur,cur指向自己的next。循环结束之后,返回pre即可。下面结合代码体会一下这个过程。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* reverseList(ListNode* head) {
    
    
        ListNode* pre = nullptr;
        ListNode* cur = head;
        while(cur != nullptr)//在确认cur不是空指针时为tail赋值
        {
    
    
            ListNode* tail = cur->next;
            cur -> next = pre;
            pre = cur;
            cur = tail;
        }
        return pre;
    }
};

2 Leetcode92题-反转链表II

反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL

这道题是上一道的升级版,要求我们做一个局部反转,题目给好了待反转的区间。这道题我认为要关注4个位置,以示例输入为例,首先是起始反转的节点,在示例中便是2;第二个是起始反转节点的上一个节点,题目中为1;第三个是结束反转时的节点,题目中是4,最后一个是结束反转时的节点的下一个节点。我们操作pre和cur到达待反转的区域时,记录好上述四个节点,反转结束时将起始反转节点的上一个节点指向结束反转时的节点(1->4);将起始反转的节点指向结束反转时的节点的下一个节点(2->5)。
下面结合代码看一下

/**
 * 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) 
    {
    
    
        ListNode* pre = nullptr,*cur = head;
        ListNode *leftEnd,*rightEnd;
        for(int i = 1; i < m; ++i)//cur到达开始反转的上一个节点
        {
    
    
            pre = cur;
            cur =  cur->next;
        }
        leftEnd = pre;//记录节点
        pre = cur;
        cur = cur->next;//cur到达待反转节点
        rightEnd = pre;
        for(int i = m; i < n; ++i)
        {
    
    
            ListNode* tail = cur->next;
            cur -> next = pre;
            pre = cur;
            cur = tail;
        }
        //结束反转之后pre就是结束反转的节点的位置
        if(leftEnd)
            leftEnd->next = pre;
        if(rightEnd)
            rightEnd->next = cur;
        if(m == 1)//如果m==1,对头节点进行了修改,返回pre
            return pre;
        return head;//其余情况返回head
    }
};

猜你喜欢

转载自blog.csdn.net/MoonWisher_liang/article/details/108040130