链表-反转链表

52 阅读1分钟

剑指 Offer 24. 反转链表

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

示例:

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

题解1: 利用栈

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    if(!head) return head
    const stack = []
    while(head){
        stack.push(head)
        head = head.next
    }
    const returnNode = stack[stack.length - 1]
    while(stack.length){
        const node = stack.pop()
        node.next = stack[stack.length - 1] || null
    }

    return returnNode
};

题解2: 双指针 -> 时间O(N)空间O(1)

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    let cur,pre;
    cur = head;
    pre = null;

    while(cur){
        let temp = cur.next;
        cur.next = pre;

        pre = cur;
        cur = temp
    }

    return pre
};

题解3: 递归 -> 时间O(N)空间O(N)

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    const recur = (cur, pre) => {
        // 返回尾节点
        if(!cur) return pre
        const head = recur(cur.next,cur)
        // 回溯时执行,使指针指向前一个节点
        cur.next = pre
        return head
    }
    return recur(head,null)
};

规则:

ListNode为节点对象 next指向下一节点;(双指针)控制指针走向,temp保存下一节点的地址,cur改变节点next指向,pre记录temp的前一个节点地址;(递归)后继节点并记录返回值,回溯时修改各节点的next引用指向。

题目来源:leetcode