@author: sdubrz
@date: 7/25/2020 10:46:14 AM
难度: 简单
考察内容: 链表
@e-mail: lwyz521604#163.com
题目来自《剑指offer》 电子工业出版社
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
解法一 栈
对于颠倒顺序的问题,最容易想到的解法就是用栈来实现:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null) {
return null;
}
if(head.next==null) {
return head;
}
// 剩下的情况就是链表中至少有两个节点的情况
Stack<ListNode> stack = new Stack<>();
ListNode current = head;
while(current!=null) {
stack.push(current);
current = current.next;
}
ListNode list2 = stack.pop();
ListNode current2 = list2;
while(stack.size()>1) {
current2.next = stack.pop();
current2 = current2.next;
}
ListNode lastNode = stack.pop();
lastNode.next = null;
current2.next = lastNode;
return list2;
}
}
但是对于链表的反转问题,栈的解法效率并不高。
执行结果:通过 显示详情
执行用时:1 ms, 在所有 Java 提交中击败了6.67%的用户
内存消耗:39.5 MB, 在所有 Java 提交中击败了100.00%的用户
解法二 一次遍历链表
遍历一次链表,并在遍历的过程中改变next的指向关系,具体实现如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null) {
return null;
}
if(head.next==null) {
return head;
}
// 剩下的情况就是链表中至少有两个节点的情况
ListNode pre = head; // 前一个节点
ListNode current = pre.next; // 当前节点
pre.next = null;
while(current.next!=null) {
ListNode back = current.next;
current.next = pre;
pre = current;
current = back;
}
current.next = pre;
return current;
}
}
这种方法的效率要明显高于栈实现的版本:
执行结果:通过 显示详情
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:40 MB, 在所有 Java 提交中击败了100.00%的用户