题目描述:
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
一般情况下,得到一个链表都是从一个节点开始,设置一个节点的next,再到下一个节点,设置它的next,如此反复,不断从链表的尾部添加节点,得到一个链表。但是解这道题,思路要翻过来,需要从链表的头部添加节点,也就是说,一个新的节点的next是当前链表的头结点。
翻转链表是这样一个过程:
设置三个指针,分别是pre,cur,next,pre就是已经处理好的链表,他的头节点就是上次处理过的节点,cur就是要插入到新链表的节点,用cur的next指向pre的头结点。但是这样就直接覆盖了原来链表的顺序,出现断开的情况。所以还有有一个next,用来存放cur节点在原来的顺序上的下一个节点,它就是下一个要处理的节点。当cur节点的下一个节点指向pre,处理就完成了,这时用cur覆盖原来的pre,用预存起来的next覆盖当前的cur,准备处理下一个节点。
代码(Java):
public class doingmyself {
public static void main(String[] args) {
int[] nums = {1,2,3,4,5};
List<ListNode> list = new ArrayList<ListNode>();
for(int num:nums) {
ListNode node = new ListNode(num);
list.add(node);
}
for(int i = 0;i<list.size()-1;i++) {
list.get(i).next = list.get(i+1);
}
ListNode head = list.get(0);
ListNode ans = reverseList(head);
System.out.println();
}
public static ListNode reverseList(ListNode head) {
if(head == null || head.next == null) { //输入的链表为空,或者输入的链表只有一个节点,直接返回这个链表
return head;
}
//设置三个指针,分表表示当前节点,前一个节点,后一个节点
//前一个节点应该成为后一个节点的next,但是直接覆盖了就会丢失原来链表的下一个节点,所以首先应该把原来链表中前一个节点的next存起来
ListNode cur = head; //当前所在的节点
ListNode next = cur.next; //按照原来链表中的顺序,当前节点的next
ListNode pre = null; //上一个处理的节点,他应该被设为修改顺序后,当前节点的next
while(next != null) { //原来顺序中,只要下一个节点不为空,就执行循环
next = cur.next; //先把当前节点的next事先存起来,避免被覆盖后链表断开
cur.next = pre; //当前节点的next应该是上一次循环处理的节点
pre = cur; //这一次处理完了,当前节点就成为下一次循环的pre
cur = next; //再把预先存起来的next节点拿出来,按原来的顺序,他是下一个要处理的节点
}
return pre; //循环完成之后,pre就是更新顺序后的头结点。
}
}
class ListNode{
int val;
ListNode next;
ListNode(int x){
val = x;
}
}