单链表反转 Java 《剑指offer》,Leetcode 206. Reverse Linked List

98 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情

Given the head of a singly linked list, reverse the list, and return

the reversed list

.

Example 1:

Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]

Example 2:

Input: head = [1,2]
Output: [2,1]

Example 3:

Input: head = []
Output: []

Constraints:

  • The number of nodes in the list is the range [0, 5000].
  • -5000 <= Node.val <= 5000

Follow up: A linked list can be reversed either iteratively or recursively. Could you implement both?

package com.offer;
 
/**
 * @Author you guess
 * @Date 2020/12/5 09:50
 * @Version 1.0
 * @Desc
 */
 
 
class ListNode {
    int val;
    ListNode next;
 
    ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}
 
 
public class Leetcode_206_ReverseLinkedList {
 
 /*   static class ListNode {
        int val;
        ListNode next;
        ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    }*/
 
 
 
    /**
     * 更喜欢这个方法!!!
     * 20220404
     * <p>
     * 方法1:cur起始指向第1个节点,prev起始指向null
     * <p>
     * Runtime: 0 ms, faster than 100.00% of Java online submissions for Reverse Linked List.
     * Memory Usage: 44 MB, less than 6.23% of Java online submissions for Reverse Linked List.
     *
     * @param head
     * @return
     */
    public ListNode reverseListSolution(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        ListNode nextTemp = null;
        while (curr != null) {
            nextTemp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = nextTemp;
        }
        return prev;
    }
 
 
    /**
     * 方法2:cur起始指向第二个节点,prev起始指向第一个节点
     * <p>
     * Runtime: 0 ms, faster than 100.00% of Java online submissions for Reverse Linked List.
     * Memory Usage: 38.9 MB, less than 46.11% of Java online submissions for Reverse Linked List.
     * <p>
     * pre = cur.next;
     * cur.next = pre;
     * 以上2行是有区别的!!!!!
     *
     * @param head
     * @return
     */
    public ListNode reverseList(ListNode head) {
 
        if (head == null)
            return null;
 
        ListNode pre = head;//指向第1个节点
        ListNode cur = head.next;//指向第2个节点
        ListNode post = null;
        //ListNode post = head.next.next;//只有1个节点时报错NullPointerException,1->null,null.next报错NullPointerException
 
        //此时pre是头指针,需要把next指针断掉,不然后面1<->2互相next会形成环,造成死循环;
        //并且不能在while中写本行代码,不然pre往前的指向就断了!
        pre.next = null;
 
        while (cur != null) {
            post = cur.next;//提前把下一个节点取到
            cur.next = pre; //pre指针不变,变化的是cur.next,此时是要修改cur.next,所以不能写成pre=cur.next;
            pre = cur; //cur指针不变,变化的是pre指针。pre,cur,post依次向前
            cur = post;
        }
        return pre;
    }
 
    public void printListNode(ListNode head) {
        while (head != null) {
            System.out.println(head.val);
            head = head.next;
        }
    }
 
    public static void main(String[] args) {
        ListNode node5 = new ListNode(5, null);
        ListNode node4 = new ListNode(4, node5);
        ListNode node3 = new ListNode(3, node4);
        ListNode node2 = new ListNode(2, node3);
        ListNode node1 = new ListNode(1, node2);
 
        Leetcode_206_ReverseLinkedList main = new Leetcode_206_ReverseLinkedList();
        main.printListNode(main.reverseList(node1));
//        输出:
//        5
//        4
//        3
//        2
//        1
    }
 
}

end