这道题,我依然用的最暴力的方法,相当于重新构造了一个链表。
因为之前写C++比较多,对于java的基础不是很好,这里因为要用到copy。用C++的链表思维理解可能会有偏差,
这里简单讲一下java的三种copy:
将一个对象的引用复制给另外一个对象,一共有三种方式。第一种方式是直接赋值,第二种方式是浅拷贝,第三种是深拷贝。所以大家知道了哈,这三种概念实际上都是为了拷贝对象啊。
1、直接赋值。在Java中,A a1 = a2,我们需要理解的是这实际上复制的是引用,也就是说a1和a2指向的是同一个对象。因此,当a1变化的时候,a2里面的成员变量也会跟着变化。
2、浅拷贝。创建一个新对象,然后将当前对象的非静态字段复制到该新对象,如果字段是值类型的,那么对该字段执行复制;如果该字段是引用类型的话,则复制引用但不复制引用的对象。因此,原始对象及其副本引用同一个对象。
3、创建一个新对象,然后将当前对象的非静态字段复制到该新对象,无论该字段是值类型的还是引用类型,都乖乖的进行复制
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.*;
public class Solution {
public ListNode ReverseList(ListNode head) {
if(null == head){
return null;
}
ListNode tmp = new ListNode(head.val);//不能使用直接赋值。
head=head.next;
while(null != head){
ListNode temp = new ListNode(head.val);//不能使用直接赋值。
temp.next = tmp;
tmp = temp;
head=head.next;
}
return tmp;
}
}
2、递归法
这种递归的思路感觉还是比较巧妙的,可能是我个人的递归写的不够6吧。想到了递归,没想到怎么递归。虽然java的赋值,会是两个对象指向同一个引用。但是可以改变当前节点的下一个节点的指向,对于当前节点没有任何影响。就可以逐个改变每一个指针的的后面一个指针指向当前指针。并把当前指针赋值为null。反正在下一层递归的时候会改变它的指向。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.*;
public class Solution {
public ListNode ReverseList(ListNode head) {
if(null == head || head.next == null){
return head;
}
ListNode temp = ReverseList(head.next);
head.next.next = head;
head.next=null;
return temp;
}
}
3、设置前、后两个指针。用后指针记录当前指针的后面一个指针。改变当前指针指向前面那个指针。然后让前指针一直指向前面那个链表。再把后指针赋值给当前指针。其实感觉和我的写法差不太远。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.*;
public class Solution {
public ListNode ReverseList(ListNode head) {
ListNode pre = null;
ListNode next = null;
while(head!=null){
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
}