今天在做Leetcode时,刷到了这道题,刚开始觉得下手非常简单,但是越想越觉得需要考虑的东西很多,想了很长时间终于能够用迭代的方式解决,递归方式通过网上的实例能够理解,但是如果自己来设计,恐怕很难想到如此巧妙的方法。
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
以上是题干部分,迭代解决的思想相对来说更加容易。我们只需要从头部开始进行遍历,从第二个元素开始,让它指向前一个节点即可。需要注意的是,我们需要维护几个引用来完成这个过程,防止出现节点丢失的情况。
public ListNode solution(ListNode head){
ListNode currentNode = head;//当前节点
ListNode prev = null;//前一个节点
ListNode nextNode = null;// 后一个节点
//如果头节点为空或者链表只有一个头节点,直接返回该节点
if(head == null || head.next == null)
return head;
//进行循环,当当前节点不为空时
while(currentNode != null){
//设置后一个节点
nextNode = currentNode.next;
//当前节点指向前一个节点,在第一个结点时,将指向null
currentNode.next = prev;
//将当前节点和前节点都向后移动
currentNode = nextNode;
prev = currentNode;
}
return prev;
}
接下来我们看一下递归是怎样处理这个问题
递归处理必然会寻找到最后一个节点,然后依次指向前一个节点,但因为链表为单链表,我们不能只获得最后一个节点,否则将无法处理。必须通过递归来获得最后一个节点和倒数第二个节点,这样才能改变其指向。
public ListNode solution(ListNode head){
//判断条件,同时也是递归的终止条件
if(head == null || head.next == null)
return head;
ListNode currentNode = solution(head.next);
//当前节点的下一个节点指针指向当前节点
head.next.next = head;
//同时将当前节点指针置为空,防止相互指向
head.next = null;
return currentNode;
}