题目
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
题目链接:
迭代
迭代的思路比较简单,反转一个链表,只需要让每个节点指向上一个节点
算法思路:
- 用一个变量来存储迭代结果 iterResult,初始化为 null
- 需要将当前节点指向的下一个节点备份 tempNextNode = curNode.next
- 当前节点的 next 指针指向上一个迭代结果 curNode.next = iterResult
- 更新迭代结果 iterResult = curNode
- 遍历下一个节点 curNode = tempNextNode,这就是第二步备份的原因,方便正常遍历原链表
实现代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode iterResult = null;
ListNode curNode = head;
while (curNode != null) {
// 先保存下一个节点
ListNode tempNextNode = curNode.next;
// 当前节点指向之前保存的上一个节点
curNode.next = iterResult;
// 遍历下一个节点,把当前节点作为本次迭代结果
iterResult = curNode;
curNode = tempNextNode;
}
return iterResult;
}
}
递归
递归大法就厉害啦,思路还是一样的,让每个节点都指向上一个节点。
算法思路:
- 递归出口,遍历链表直到链表尾部即返回,也就是 curNode.next = null
- 递归参数,不断遍历下一个节点,递归参数就设定为 curNode.next
- 让当前节点的下一个节点指向当前节点(有点拗口啊),即curNode.next.next = curNode
实现代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
// 设置递归出口
if (head == null || head.next == null) return head;
// 存放迭代结果
ListNode pre = reverseList(head.next);
// 让当前节点的下一个元素指向当前元素
head.next.next = head;
// 切断当前元素原本的指向(所有指针都反向了,因此原来的正向指针无效)
head.next = null;
return pre;
}
}
递归过程如下: