题目:
描述
给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
数据范围: 0≤�≤10000≤n≤1000
要求:空间复杂度 �(1)O(1) ,时间复杂度 �(�)O(n) 。
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
示例1
输入:
{1,2,3}
复制返回值:
{3,2,1}
示例2
输入:
{}
返回值:
{}
说明:
空链表则输出空
先放代码
// struct ListNode { // int val; // struct ListNode *next; // }; /** * * @param pHead ListNode类 * @return ListNode类 */ #include <stdio.h> #include <stdlib.h> struct ListNode* ReverseList(struct ListNode* pHead ) { // write code here struct ListNode *p=NULL;//过去节点 struct ListNode *H=pHead;//现在节点 struct ListNode *k=NULL;//未来节点 while (H) { k=H->next; H->next=p; p=H; H=k; } return p; }
分享一下我对这道题的理解
本质上是对链表的遍历,但又不完全一样
区别在于:在遍历的同时需要把下一个节点的地址赋值为上一个节点的地址,并且还要保证下一次移动的正常运行
也就是说,需要将一个节点的上一个节点的位置和下一个节点的位置都记住,还要记住自己本身的位置(因为要作为终止循环的条件) 所以我将这三个节点分别命名为过去节点,现在节点和未来节点
我们将未来节点先移动一位 也就是
k=H->next;
然后还要记住上一个节点的位置,而上一个节点正是对于新节点来说下一个节点的位置所以
H->next=p;
这样一来,过去,未来的节点都被记住了,于是乎,过去节点和现在节点都要向前移动,过去节点先赋值为现在节点,现在节点再赋值为未来节点,那么这一轮循环便结束了(也就是过去成为了现在,而现在又到了未来)
p=H;
H=k;
循环到了最后时,因为原先旧节点的尾节点的next指向了NULL根据上面的步骤k(未来),H(现在)都指向了NULL,只有p留在了尾节点上成为了新链表的头节点,终止循环返回p
以上是我对这道题的理解