反转链表的多种方式

题目:反转链表

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

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

题解:

题目不难,定义三个变量pre、cur、next,分别记录上一个结点,当前结点、下一个结点。通过迭代,依次反转结点指向。代码如下:

/**
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode pre = null,cur =head ,next = null;
        while(cur != null){
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur =next;
        }
        return pre;

    }
}

当然,本题除了使用迭代方式外,还可以使用递归的方式解答。

最初我是通过递归直到找到链表的倒数第二个结点,然后将下一个结点的的下一个结点指向本结点,并将尾结点作为首结点递归返回。代码如下:

public ListNode reverseList(ListNode head) {
    if(head == null ||head.next == null){
    	return head;
    }
    ListNode h =null;
    //使用方法递归,直到链表的倒数第二个结点
    if(head.next.next!=null){
    	h = reverseList(head.next);
    }
    //将结点的下个结点指向本结点
    ListNode node = head.next;
    node.next = head;
    head.next = null;
    /*
    如果h为空,说明没有执行方法递归,即h的下个结点为尾结点,
    则将尾结点作为首结点返回
    */
    if(h == null){
    	return node;
    }
    //否则则直接返回h结点,即反转后的首结点
    return h;

}

上面的代码写的有些繁琐,还可以进行适当优化,通过方法递归,如果当前结点或者下一个结点为null时,直接返回当前结点作为首结点。否则将下一个结点的下一个结点指向当前结点,并将当前结点的下一个结点置空,实现链表的反转。

public ListNode reverseList(ListNode head) {
    if(head == null ||head.next == null){
        return head;
    }
    ListNode h = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return h;
}

最后,能使用递归解决的问题,一定可以通过迭代解决,并且方法的递归对内存的开销较大。

阅读原文

posted @ 2020-10-30 11:41  无尽白日梦  阅读(138)  评论(0)    收藏  举报