题目描述
// 力扣
// 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
// 牛客
// 输入一个链表,反转链表后,输出新链表的表头。
题解
// 方法应该有很多
//////////////////////////////// 直接法 //////////////////////////////
// 笨办法,直接遍历所有元素,存起来,再倒叙提取出来放进新构造的链表中
// 牛客
// 运行时间:12ms
// 占用内存:9920k
import java.util.Stack;
public class Solution {
public ListNode ReverseList(ListNode head) {
if (head == null)
return head;
// 新建一个栈stack存储链表元素val,弹出的val正好是反转顺序
Stack<Integer> stack = new Stack<>();
ListNode index = head; // 初始化链表索引,从头遍历链表
// while循环直到index到达链表尾后一位才停止,
// 所以循环结束后index会到达链表尾结点的下一个位置
// 我们将这个位置作为新链表的头结点,开始创建新链表
while (index != null) {
stack.push(index.val); // 每遍历个结点就将val压入栈存储
index = index.next; // 所以index右移
}
// index位置创建新结点,弹出一次stack存的val
index = new ListNode(stack.pop());
// 当前index位置作为新链表的头结点,创建一个指向记为result
ListNode result = index;
// index右移创建新结点,弹出stack存储的元素作为新结点的元素,
while (!stack.isEmpty()) {
index.next = new ListNode(stack.pop()); // 创建新结点
index = index.next; // index右移
}
return result; // 返回刚刚新链表(片段)的头结点
}
}
// 力扣
// 执行用时:2 ms, 在所有 Java 提交中击败了7.85%的用户
// 内存消耗:38.2 MB, 在所有 Java 提交中击败了71.94%的用户
import java.util.Stack;
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null)
return head;
Stack<Integer> stack = new Stack<>();
ListNode index = head;
while (index != null) {
stack.push(index.val);
index = index.next;
}
index = new ListNode(stack.pop());
ListNode result = index;
while (!stack.isEmpty()) {
index.next = new ListNode(stack.pop());
index = index.next;
}
return result;
}
}
//////////////////////////////// 头插法 /////////////////////////
// 这个方法画图就懂了,是比较推荐的方法
// 牛客
// 运行时间:10ms
// 占用内存:9780k
public class Solution {
public ListNode ReverseList(ListNode head) {
if (head == null)
return head;
ListNode newList = new ListNode(-1);
while (head != null) {
ListNode next = head.next;
head.next = newList.next;
newList.next = head;
head = next;
}
return newList.next;
}
}
// 力扣
// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:38 MB, 在所有 Java 提交中击败了91.31%的用户
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null)
return head;
ListNode newList = new ListNode(-1);
while (head != null) {
ListNode next = head.next;
head.next = newList.next;
newList.next = head;
head = next;
}
return newList.next;
}
}
////////////////////////////// 三指针法 ////////////////////////////
// 也是比较推荐的方法,我画一个示意图方便理解
// 力扣
// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:38 MB, 在所有 Java 提交中击败了92.77%的用户
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode pre = null;
ListNode nex = null;
ListNode cur = head;
while (cur != null) {
nex = cur.next;
cur.next = pre;
pre = cur;
cur = nex;
}
return pre;
}
}
// 牛客
// 运行时间:11ms
// 占用内存:9876k
public class Solution {
public ListNode ReverseList(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode pre = null;
ListNode nex = null;
ListNode cur = head;
while (cur != null) {
nex = cur.next;
cur.next = pre;
pre = cur;
cur = nex;
}
return pre;
}
}
三指针法示意图:
///////////////////////////// 递归法 /////////////////////////
// 力扣
// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:38.5 MB, 在所有 Java 提交中击败了32.42%的用户
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode next = head.next;
head.next = null;
ListNode newHead = reverseList(next);
next.next = head;
return newHead;
}
}
// 牛客
// 运行时间:12ms
// 占用内存:10048k
public class Solution {
public ListNode ReverseList(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode next = head.next;
head.next = null;
ListNode newHead = ReverseList(next);
next.next = head;
return newHead;
}
}