【剑指offer】24. 反转链表

115 阅读2分钟

题目描述

在这里插入图片描述 在这里插入图片描述

// 力扣
// 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

// 牛客
// 输入一个链表,反转链表后,输出新链表的表头。

题解

// 方法应该有很多

//////////////////////////////// 直接法 //////////////////////////////
// 笨办法,直接遍历所有元素,存起来,再倒叙提取出来放进新构造的链表中

// 牛客
// 运行时间: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;
    }
}