力扣 206. 反转链表

题目来源:https://leetcode.cn/problems/reverse-linked-list/description/

 

 C++题解1:声明一个vector<int> 数据类型,将原链表中的数据存放进容器,再用一个新链表,从容器末端一一读取元素,从而实现链表反转。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* ptr = head, *revptr = nullptr;
        vector<int> a(0);
        if(head == nullptr) return nullptr;
        while(ptr){
            a.push_back(ptr->val);
            ptr = ptr->next;
        }

        int len = a.size();
        revptr = new ListNode(a[len-1]);
        ListNode* curptr = revptr;
        for(int ii = len-2; ii >= 0; ii--){
            ptr = new ListNode(a[ii]);
            curptr->next = ptr;
            curptr = curptr->next;
        }

        return revptr;
    }
};

C++题解2:声明三个指针,一个指向上一个节点preptr,一个指向当前节点curptr,一个指向下一个节点。从原链表往下走,curptr的指针反向指向preptr,preptr指针更新到curptr;如果nexptr的next不为空,那么curptr走到nexptr,nexptr走向nexptr->next;但如果nexptr的next为空,那么nexptr得指向curptr,然后curptr走到nexptr,才能使原链表的末尾节点指向倒数第二个节点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head) return nullptr;
        ListNode* preptr = nullptr, *curptr = head, *nexptr = head->next; 
        while(nexptr){
            curptr->next = preptr;
            preptr = curptr;
            if(nexptr->next){
                curptr = nexptr;
                nexptr = nexptr->next;
            }
            else {
                nexptr->next = curptr;
                curptr = nexptr;
                break;
            }
        }
        return curptr;
    }
};

两种解法都要单独考虑原链表为空的情况。

网上解法1:大致思路与题解2相同,简洁一点点,因为题解2指针多走了一步

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* temp; // 保存cur的下一个节点
        ListNode* cur = head;
        ListNode* pre = NULL;
        while(cur) {
            temp = cur->next;  // 保存一下 cur的下一个节点,因为接下来要改变cur->next
            cur->next = pre; // 翻转操作
            // 更新pre 和 cur指针
            pre = cur;
            cur = temp;
        }
        return pre;
    }
};

网上解法2:递归法。last可以不断递归直到指向末节点再往回走。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        // 边缘条件判断
        if(head == NULL) return NULL;
        if (head->next == NULL) return head;
        
        // 递归调用,翻转第二个节点开始往后的链表
        ListNode *last = reverseList(head->next);
        // 翻转头节点与第二个节点的指向
        head->next->next = head;
        // 此时的 head 节点为尾节点,next 需要指向 NULL
        head->next = NULL;
        return last;
    }
}; 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值