您的位置:首页 > 其它

LeetCode Reverse Linked List翻转链表

2018-04-10 13:23 507 查看
Reverse a singly linked list.
题目只有一句话,刚看到这道题时觉着没有什么难度,通过集合类LinkedList提供的一些方法先遍历再进行反向插入就好了,然看到题目给出的方法才知道它是不能使用集合类的,只能通过自定义的链表实现翻转。然后就有点懵了,可能是自己链表、指针方面的知识有点薄弱吧,想了好久没有思路,去网上查了查资料,觉着这道题真心不错,至少可以巩固扎实自己的基础知识,也让我认识到了自己的这方面的不足,尤其是对递归而言,理解起来会比较困难,怎样去弥补呢,自然是多做一些递归方面的题培养自己递归解决问题的思想了,额额......
这道题呢,算是面试中比较经典的题了,它有两种解法递归和迭代,个人觉着迭代比较简单,递归的话翻转指针来说一开始没能够理解,现在多用断点调试再想一下就差不多了,这里我先给大家分享一下这两种方法的思想。
迭代方式
迭代的方式是从链头开始处理,如下图给定一个存放5个数的链表。



  首先对于链表设置两个指针:



  然后依次将旧链表上每一项添加在新链表的后面,然后新链表的头指针NewH移向新的链表头,如下图所示此处需要注意,不可以上来立即将上图中P->next直接指向NewH,这样存放2的地址就会被丢弃,后续链表保存的数据也随之无法访问。而是应该设置一个临时指针tmp,先暂时指向P->next指向的地址空间,保存原链表后续数据。然后再让P->next指向NewH,最后P=tmp就可以取回原链表的数据了,所有循环访问也可以继续展开下去



  指针继续向后移动,直到P指针指向NULL停止迭代。



  最后一步:


下面是我自己的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的地址空间。



  然后H指针逐层返回的时候依次做下图的处理,将H指向的地址赋值给H->next->next指针,并且一定要记得让H->next =NULL,也就是断开现在指针的链接,否则新的链表形成了环,下一层H->next->next赋值的时候会覆盖后续的值。



  继续返回操作:



  上图第一次如果没有将存放4空间的next指针赋值指向NULL,第二次H->next->next=H,就会将存放5的地址空间覆盖为3,这样链表一切都大乱了。接着逐层返回下去,直到对存放1的地址空间处理。



  返回到头:


下面是我的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;
}
}
}
我觉着大家根据图解再去了解代码会明确很多,两种方式都很值得学习,我们应该花较长的时间去内化掌握它,再接再厉哈...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息