反转链表的两种方法

简介: 反转链表的两种方法

大家好,今天和大家分享的是反转链表的两种方法,第一种是用泛型编程里面的STL,第二种是利用多个指针进行操作,小孩子才做选择,建议两个都学。我们往下看:


一.使用vector容器


ps:该方法对内存的需求较高,这是个缺点,可以直接使用STL容器自带的reverse进行反转(将vector容器内的结点进行反转,然后再用for循环将他串联起来),实现起来相对容易,思路不太复杂。


请看以下代码:

typedef struct Node
{
 int val;
  struct Node*next;
}ListNode;
class traverse {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if (!pHead) return nullptr;
        vector<ListNode*> v;
        while (pHead) {
            v.push_back(pHead);
            pHead = pHead->next;
        }
        reverse(v.begin(), v.end()); // 反转vector,也可以逆向遍历
        ListNode *head = v[0];
        ListNode *cur = head;
        for (int i=1; i<v.size(); ++i) { // 构造链表
            cur->next = v[i]; // 当前节点的下一个指针指向下一个节点
            cur = cur->next; // 当前节点后移
        }
        cur->next = nullptr; // 切记最后一个节点的下一个指针指向nullptr
        return head;
    }
};


此方法的复杂度:


时间复杂度:O(n)

空间复杂度:O(n), 用了一个vector来存单链表


二.调整指针法


ps:此方法更加妥当,能得到更多人的青睐,很好的利用几个指针的指向反转一个链表。


初始化:3个指针


1)pre指针指向已经反转好的链表的最后一个节点,最开始没有反转,所以指向nullptr


2)cur指针指向待反转链表的第一个节点,最开始第一个节点待反转,所以指向head


3)nex指针指向待反转链表的第二个节点,目的是保存链表,因为cur改变指向后,后面的链表则失效了,所以需要保存


接下来,循环执行以下三个操作


1)nex = cur->next, 保存作用


2)cur->next = pre 未反转链表的第一个节点的下个指针指向已反转链表的最后一个节点


3)pre = cur, cur = nex; 指针后移,操作下一个未反转链表的第一个节点


循环条件,当然是cur != nullptr


循环结束后,cur当然为nullptr,所以返回pre,即为反转后的头结点


这里以1->2->3->4->5 举例:


5005d791ec047c62a65621d65e3c1230.png


5a84b0ffc1aeb2bb83af047be5ddef8a.png



f307d9a9c133d514694586b674f19fbe.png


0bd765acc3fedc90a4c731b4ec2d033e.png


代码如下:


class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode *pre = nullptr;
        ListNode *cur = pHead;
        ListNode *nex = nullptr; // 这里可以指向nullptr,循环里面要重新指向
        while (cur) {
            nex = cur->next;
            cur->next = pre;
            pre = cur;
            cur = nex;
        }
        return pre;
    }
};


此方法复杂度:


时间复杂度:O(n), 遍历一次链表

空间复杂度:O(1)


总结:要从易懂的角度来看,第一种不失是好的,使用STL,我现在才大一,我听说一些面试是不允许使用STL这一内容解体的。第二种方法很妙,复杂度是比较理想的,而且用到了灵魂指针的应用。建议大家多琢磨一下第二种方法。


希望能帮助你解决这一块的问题,可以点个赞,关个注,评个论,我们一起进步,加油!


2023.02.08


From:努力进大厂的新青年

相关文章
|
16天前
|
存储 Java
HashMap之链表转红黑树(树化 )-treefyBin方法源码解读(所有涉及到的方法均有详细解读,欢迎指正)
本文详细解析了Java HashMap中链表转红黑树的机制,包括树化条件(链表长度达8且数组长度≥64)及转换流程,确保高效处理大量数据。
48 1
|
5月前
|
SQL 算法 数据可视化
LeetCode题目92:反转链表ll 【python 递归与迭代方法全解析】
LeetCode题目92:反转链表ll 【python 递归与迭代方法全解析】
|
6月前
链表的几种常见方法
链表的几种常见方法
25 1
|
存储 C++ 容器
五道超经典题目,带你手撕链表题(多种方法实现)下
五道超经典题目,带你手撕链表题(多种方法实现)
58 1
力扣203移除链表元素:思路分析+代码实现+方法总结(伪头节点法&递归)
力扣203移除链表元素:思路分析+代码实现+方法总结(伪头节点法&递归)
94 0
|
容器
力扣206反转链表:代码实现+图文全解+方法总结(四种方法)
力扣206反转链表:代码实现+图文全解+方法总结(四种方法)
162 0
|
6月前
|
存储 Java
【链表的说明、方法---顺序表与链表的区别】
【链表的说明、方法---顺序表与链表的区别】
61 0
|
6月前
【数据结构】双向链表中删除节点的方法实现(代码+详解)
【数据结构】双向链表中删除节点的方法实现(代码+详解)
226 0
|
11月前
|
存储 程序员 API
数据结构单链表之查看数组与链表的方法 | 第六套-2
数据结构单链表之查看数组与链表的方法 | 第六套-2
90 0
|
11月前
|
存储 数据可视化 索引
数据结构单链表之查看数组与链表的方法 | 第六套-1
数据结构单链表之查看数组与链表的方法 | 第六套-1
61 0