Idiot-maker

  :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

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;
    }
}

 

posted on 2015-05-19 16:33  NickyYe  阅读(214)  评论(0)    收藏  举报