目录主题概要和代码思路代码示例总结
主题概述
定义函数,输入链表的第一个节点,反转链表,输出反转后的链表的第一个节点
示例 :
输入: 1-2-3-4-5-NULL
输出: 5-4-3-2-1-NULL
附加leetcode链接:
单击此处进入leetcode
思路和代码思路表明逆转链表这个主题的思路非常巧妙。 这里对迭代法进行说明。
迭代法的思路如下。
1:首先定义cur指针,它首先指向我们头上的节点Head,然后开始向下遍历。 cur指针的作用是记录我们要翻转的节点。
2:然后定义用于记录当前需要反转的节点的前体的prev指针。
3:然后定义用于保存下一个要翻转的节点的curNext指针。
4:最后定义newHead指针,存储反转链表的起始节点。
翻转链表的中心语句共有4个步骤。
)1) :首先,保存下一个要反转的节点。 如果不保存,则prev的初始值为null,因此执行cur.next=prev后,如果此时只有一个相当于链表的节点,则下一个要反转的节点将丢失。 为了避免出现这种情况,每次翻转时都必须拿着curNext指针进行保存
)2) :的保存完成后,执行语句cur.next=prev,接下来是反转链表,所以反转的节点的next域中将存储其前一个前驱节点的地址。
当然,在运行cur.next=prev之前,还需要对名为curNext的指针进行非空判断。 如果为null,则存在两种情况。
情况1 )如果说明此时链表内部只有一个节点,即使反转也仍然是原来的节点,所以将cur直接分配给newHead并返回。
情况2:表示此时cur指针已遍历到最后一个节点。 最后一个节点是我们反转的新链表的开头节点,可以直接将当前cur指定给newHead并返回。
)3) :在prev中保存每次被反转的节点。 这是因为,被反转的节点每次都会成为下一个被反转节点的后继节点,以防下一个被反转的节点找不到他的后继节点(该后继节点之前是下一个被反转节点的反转前的前驱节点) )
)4) :反转后,cur继续遍历。 注意这里的遍历语句是cur=curNext; 不能写cur=cur.next。
代码示例class solution { publiclistnodereverselist (listnode head ) { ListNode cur=head; listnode prev=空; ListNode newHead=null; if(head==null ) { return null; }while(cur!=null } { listnodecurnext=cur.next; if (cur next==null ) ({ new head=cur; } cur.next=prev; prev=cur; cur=curNext; } return newHead; }总结迭代法是最常用的方法,其时间复杂度为o(n )。 最坏的情况下,因为需要遍历一次链表并结束),假设链表中有n个节点),空间复杂度为o )1)。
当然还有一种方法是递归法,很难理解。 如果大家感兴趣的话,请去leetcode公式自己看代码和分析。