Reverse a singly linked list.
题目只有一句话,刚看到这道题时觉着没有什么难度,通过集合类LinkedList提供的一些方法先遍历再进行反向插入就好了,然看到题目给出的方法才知道它是不能使用集合类的,只能通过自定义的链表实现翻转。然后就有点懵了,可能是自己链表、指针方面的知识有点薄弱吧,想了好久没有思路,去网上查了查资料,觉着这道题真心不错,至少可以巩固扎实自己的基础知识,也让我认识到了自己的这方面的不足,尤其是对递归而言,理解起来会比较困难,怎样去弥补呢,自然是多做一些递归方面的题培养自己递归解决问题的思想了,额额......
这道题呢,算是面试中比较经典的题了,它有两种解法递归和迭代,个人觉着迭代比较简单,递归的话翻转指针来说一开始没能够理解,现在多用断点调试再想一下就差不多了,这里我先给大家分享一下这两种方法的思想。
迭代方式
迭代的方式是从链头开始处理,如下图给定一个存放5个数的链表。
首先对于链表设置两个指针:
然后依次将旧链表上每一项添加在新链表的后面,然后新链表的头指针NewH移向新的链表头,如下图所示,此处需要注意,不可以上来立即将上图中P->next直接指向NewH,这样存放2的地址就会被丢弃,后续链表保存的数据也随之无法访问。而是应该设置一个临时指针tmp,先暂时指向P->next指向的地址空间,保存原链表后续数据。然后再让P->next指向NewH,最后P=tmp就可以取回原链表的数据了,所有循环访问也可以继续展开下去。
下面是我自己的Java实现......
package com.gaoxue.LeetCode;
class ListNode{
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
public class ReverseList {
public ListNode reverseList(ListNode head) {
ListNode newHead = null;
while(head!=null) {
ListNode temp = head.next;
head.next = newHead;
newHead = head;
head = temp;
}
return newHead;
}
public static void main(String[] args) {
ListNode head = null;
ListNode dummy = null;
int x[] = new int[] {1,2,3,4,5};
for(int i=0;i<x.length;i++) {
if(head==null) {
head = new ListNode(x[i]);
dummy = head;
}else {
dummy.next = new ListNode(x[i]);
dummy = dummy.next;
}
}
ListNode head2 = new ReverseList().reverseList(head);
while(head2!=null) {
System.out.print(head2.val+" ");
head2 = head2.next;
}
}
}
递归方式
首先指针H迭代到底如下图所示,并且设置一个新的指针作为翻转后的链表的头。由于整个链表翻转之后的头就是最后一个数,所以整个过程NewH指针一直指向存放5的地址空间。
下面是我的Java实现......
package com.gaoxue.LeetCode;
class ListNode{
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
public class ReverseList {
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null) {
return head;
}
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
public static void main(String[] args) {
ListNode head = null;
ListNode dummy = null;
int x[] = new int[] {1,2,3,4,5};
for(int i=0;i<x.length;i++) {
if(head==null) {
head = new ListNode(x[i]);
dummy = head;
}else {
dummy.next = new ListNode(x[i]);
dummy = dummy.next;
}
}
ListNode head2 = new ReverseList().reverseList(head);
while(head2!=null) {
System.out.print(head2.val+" ");
head2 = head2.next;
}
}
}
我觉着大家根据图解再去了解代码会明确很多,两种方式都很值得学习,我们应该花较长的时间去内化掌握它,再接再厉哈...