这道题最开始还是想用递归做,但是一直卡,太菜了,本来的思路还是斐波那契一样递归到最深处,然后在尾结点处开始改变序列方向。但是我错误在改变方向的逻辑,我一直想的是在最后一个点直接反向改变next值,但是这样递归的返回值就无法控制,题目要求只能返回头结点,如此递归只能返回一个个的节点。正确答案如下:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
ListNode p=null;
public ListNode ReverseList(ListNode head) {
if(head==null||head.next==null){
return head; // 1、如果输入的头结点是 NULL,或者整个链表只有一个结点的时候
//2、链表断裂的考虑
}
p=ReverseList(head.next);//p为反转过后的头结点
head.next.next=head; //并不是反转尾结点的next指向前一个点方向
//而是在头结点后 添加数据 假装形成新队列
head.next=null; //必须变成空,不然再下一个递归的时候。
//head.next,next就是头结点p了 他被改变就完了
return p;
}}
递归还要再练,关键是掌握单链表的特点,单链表只有next(后续节点),在做这个题的辅助节点经常要考虑到后一节点,我在做这个题的时候经常想到在中间插入,即pre和 next中间插temp,这样实现会很困难。
另外一个简单的方法,非递归:
创造三个辅助点三步走,关键是前一个点,后一个点,第三个点不是他们中间的,而是后一个的后一个点。
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL) return NULL;//注意程序鲁棒性
ListNode* pNode=pHead;//当前指针
ListNode* pReverseHead=NULL;//新链表的头指针
ListNode* pPrev=NULL;//当前指针的前一个结点
while(pNode!=NULL){//当前结点不为空时才执行
ListNode* pNext=pNode->next;//链断开之前一定要保存断开位置后边的结点
if(pNext==NULL)//当pNext为空时,说明当前结点为尾节点
pReverseHead=pNode;
pNode->next=pPrev;//指针反转
pPrev=pNode;
pNode=pNext;
}
return pReverseHead;
}
}
i小宋