尝试一
结果:失败
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null){
return null;
}
return Reverse(head);
}
public ListNode Reverse(ListNode n){
if(n.next==null){
return n;
}
//寻找
ListNode r=Reverse(n.next);
ListNode nn=new ListNode(n.val);
r.next=nn;
return nn;
}
}
用例:
{1,2,3,4,5}
对应输出应该为:
{5,4,3,2,1}
你的输出为:
{1}
分析:为什么会失败?ReverseList方法中 Reverse(head)返回一个listNode时就蹦了,因为这个listNode它的next为null。其实逻辑是可以的,具体分析下来得到的链表也是这样的:
5=>4=>3=>2=>1
然而,我他妈返回的是1,有锤子的用!并且java中判断对象是否可用是用的是可达性分析算符(具体参加这篇文章 垃圾收集器及内存分配策略),所以当2,3,4,5对应的对象不可达时,它们甚至有可能被垃圾回收了。
尝试二
我看了以下讨论,发现有人是改变链表的结构。如:
1=>2=>3=>4=>5
改变next(像指针一样,然而不是)
1<=2<=3<=4<=5
这就是改变肉体骨架(next),没有改变灵魂(节点的值)。
下面是我的方法:
import java.util.ArrayList;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null){
return null;
}
//用来装灵魂(各个链表节点的值)
ArrayList<Integer> soul=new ArrayList<Integer>();
/*抽取灵魂*/
ListNode n=head;
while(n!=null){
soul.add(n.val);
n=n.next;
}
/*改变肉体(链表)的灵魂(每个节点的值)*/
n=head;
int i=soul.size();
while(i>0){
n.val=soul.get(--i);
n=n.next;
}
return head;
}
}
我的是没有改变肉体,改变了灵魂。如:
1=>2=>3=>4=>5
改变next(像指针一样,然而不是)
5=>4=>3=>2=>1
尝试三
虽然,尝试一可行。但是感觉有点投机倒把的赶紧,没有用到链表的知识。看了一下讨论,得出尝试二:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null || head.next==null){
return head;
}
ListNode l=null;
ListNode r=head;
do{
//赶紧把下一个要处理的节点用head存起来,不然等一下找不到。
head=r.next;
//改变指向了
r.next=l;
/*开始移动l与r了*/
l=r;
//幸好之前把下一个要处理的节点用head存起来,不然就找不到了
r=head;
}while(r!=null);
return l;
}
}
结果:通过
本文探讨了链表逆序的三种实现方法,包括递归、改变链表节点指向和改变节点值。详细分析了每种方法的优缺点,特别强调了在Java环境下避免对象不可达导致的潜在问题。
1093

被折叠的 条评论
为什么被折叠?



