1.题目描述
2.题解
i.双指针法
--运用两个指针,在遍历的过程中翻转节点的next实现链表的翻转。
--有个细节:当改变某个节点的next时,会出现该节点的下一个的节点没有其他节点指向的情况,因此造成不方便将指针向后遍历的结果,而这时应该引入一个节点来保存这个(没有其他节点指向的)节点的地址。
ii.递归
--这个方法的思路其实和双指针方法一致,只是更好的解决了双指针方法中需要一个新节点来保存其他节点的问题。
--而其中体现递归思想的一步就是:当双指针所指节点实现翻转后要向后遍历时,将这两个指针再重新放入翻转的方法中。
3.代码示例
i.双指针法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode index=null;
ListNode temp=new ListNode();//用于保存节点
while(head!=null&&head.next!=null){
//翻转操作
temp=head.next;
head.next=index;
//将指针向前移动
index=head;
head=temp;
}
temp.next=index;//循环结束后将最后一个节点指向前一个节点
return head;
}
}
ii.递归
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(null, head);
}
private ListNode reverse(ListNode prev, ListNode cur) {
if (cur == null) {
return prev;
}
ListNode temp = null;
temp = cur.next;// 先保存下一个节点
cur.next = prev;// 反转
// 更新prev、cur位置
// prev = cur;
// cur = temp;
return reverse(cur, temp);
}
}
4.问题总结
i.当较快的那个指针遍历到最后一个节点后结束循环,但要添加一个最后一个节点指向前一个节点的操作,否则最后只会输出最后一个节点。
ii.以上操作会存在的问题:
ListNode temp=new ListNode();
//……
head.next=index;
//会报错:Exception in thread "main" java.lang.NullPointerException
//at LiKouDemo.Test2.main(Test2.java:17)
ListNode temp=new ListNode();
//……
temp.next=index;
//这样写不会报错
这里的head有可能会出现空指针的情况所以要加上是否为空的判断,但由于temp是new的一个节点所以temp.next本身就是null。