Reverse Linked List

https://leetcode.com/problems/reverse-linked-list/

Reverse a singly linked list.

解题思路:

类似于插入排序,始终将当前节点插入到最前方。

/**

 * Definition for singly-linked list.

 * public class ListNode {

 *     int val;

 *     ListNode next;

 *     ListNode(int x) { val = x; }

 * }

 */

public class Solution {

    public ListNode reverseList(ListNode head) {

        if(head == null || head.next == null) {

            return head;

        }

        ListNode dummy = new ListNode(0);

        dummy.next = head;

        ListNode first = head;

        ListNode last = head;

        while(last.next != null) {

            ListNode next = last.next.next;

            dummy.next = last.next;

            dummy.next.next = first;

            last.next = next;

            first = dummy.next;

        }

        return dummy.next;

    }

}

但是这样很复杂有没有感觉到?straight forward的方法是,维护两个指针,不断向后面一个的next指向前面的就完成倒置了。

/**

 * Definition for singly-linked list.

 * public class ListNode {

 *     int val;

 *     ListNode next;

 *     ListNode(int x) { val = x; }

 * }

 */

public class Solution {

    public ListNode reverseList(ListNode head) {

        if(head == null || head.next == null) {

            return head;

        }

        ListNode pre = head;

        ListNode cur = head.next;

        head.next = null;

        while(cur != null) {

            ListNode next = cur.next;

            cur.next = pre;

            pre = cur;

            cur = next;

        }

        return pre;

    }

}

这道新题其实是很多题目的子问题,比如 Reverse Nodes in k-GroupReverse Linked List II

这道题很简单,下面写写递归的方法。首先是,插入法的递归代码。

/**

 * Definition for singly-linked list.

 * public class ListNode {

 *     int val;

 *     ListNode next;

 *     ListNode(int x) { val = x; }

 * }

 */

public class Solution {

    public ListNode reverseList(ListNode head) {

        if(head == null || head.next == null) {

            return head;

        }

        ListNode dummy = new ListNode(0);

        dummy.next = head;

        return reverse(dummy, dummy.next);

    }

    

    public ListNode reverse(ListNode dummy, ListNode pre) {

        if(pre.next == null) {

            return dummy.next;

        }

        ListNode next = pre.next.next;

        pre.next.next = dummy.next;

        dummy.next = pre.next;

        pre.next = next;

        return reverse(dummy, pre);

    }

}

上面的解法是一个尾递归,其实就是迭代的硬套。好吧,尾递归因为本层递归结束后,可以完全弹出递归栈,所以不需要额外空间,这是它好的地方。但是,在这里,却是有点硬套了。

下面是第二种迭代方法的一个递归方法,思路很简单,却不容易想到。

不断递归获取链表的后一个节点,直到尾节点。然后回溯,将后一个节点指向前一个,前一个指向空节点。

最后返回最后一个节点。

/**

 * Definition for singly-linked list.

 * public class ListNode {

 *     int val;

 *     ListNode next;

 *     ListNode(int x) { val = x; }

 * }

 */

public class Solution {

    public ListNode reverseList(ListNode head) {

        if(head == null || head.next == null) {

            return head;

        }

        ListNode next = head.next;

        ListNode end = reverseList(next);

        next.next = head;

        head.next = null;

        return end;

    }

}

 

你可能感兴趣的:(list)