BM1反转链表
描述
给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
数据范围: 0\leq n\leq10000≤n≤1000
 要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n) 。
如当输入链表{1,2,3}时,
 经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
 以上转换过程如下图所示:
示例1
输入:
{1,2,3}
 
返回值:
{3,2,1}
 
示例2
输入:
{}
 
返回值:
{}
 
说明:
 空链表则输出空
双指针法
使用一个指针cur指向头结点,另一个指针初始为nullptr,然后用一个临时变量tmp保存cur->next,因为接下来需要反转cur->next。具体反转步骤为:
- tmp保存cur->next;
 - cur->next指向pre;
 - pre向前移动变成cur的值;
 - cur向前移动变成tmp的值。
然后不断迭代。

 
图源牛客,侵删
 
/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
#include <list>
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
		ListNode* tmp;
		ListNode* cur = pHead;
		ListNode* pre = nullptr;
		while(cur){
			tmp = cur->next;
			cur->next = pre;
			pre = cur;
			cur = tmp;
		}
		return pre;
    }
};
 
递归法1
和迭代法差不多,就是感觉好绕。。
/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
#include <list>
class Solution {
public:
	ListNode* reverse(ListNode* pre, ListNode* cur){
		if(cur == nullptr) return pre;
		//pre = cur;
		//cur = tmp;
		ListNode* tmp = cur->next;
		cur->next = pre;
		return reverse(cur, tmp);
	}
    ListNode* ReverseList(ListNode* pHead) {
		return reverse(nullptr, pHead);
    }
};
 
递归法2
大致明白思路,具体这个递归的执行过程不理解,比上个还绕,,,
 半响后更新:好像又理解第二种递归法的执行了:就是pHead和pHead->next都不为空的话,就递归执行反转函数,然后接着执行当前pHead与其第二个结点的反转(把pHead的next的next指向自身,把pHead的next指向空)
/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
#include <list>
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
		if(pHead == nullptr) return nullptr;
		if(pHead->next == nullptr) return pHead;
		ListNode* ans = ReverseList(pHead->next);
		pHead->next->next = pHead;
		pHead->next = nullptr;
		return ans;
    }
};
                


















