🌈JSer LeetCode Trip: 206. Reverse Linked List

·  阅读 123

PRE

这是我参与更文挑战的第7天,活动详情查看: 更文挑战

206. Reverse Linked List

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

img

分析

单项链表的特殊之处在于下一个元素的信息会因为更改当前索引而消失 简单的暴力解可以尝试使用数组来暂时存储数据 在进行处理就好

现在考虑如何优化 时间层面是无论如何都要遍历所有的元素,因此最小也是O(N) 但空间层面是可以优化的 上述所使用的数组暴力解空间上是O(N)的复杂度 事实上,链表反转的关键在于如何变换了还不丢失之后的节点 要完成这一点并不需要保存所有的链表,而仅仅是暂时存储上一个和下一个就好 这样空间上就变成了O(1)

实现

迭代

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
  // 链表反转的关键在于如何变换了还不丢失之后的节点
  // 使用更多的指针来进行临时保存
  let prev = null
  let curr = head
  while(curr) {
    // 变换之前先保存
    const next = curr.next
    curr.next = prev
    
    prev = curr
    curr = next
  }
  return prev
};
复制代码

递归

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
  return reverse(null, head)

  function reverse(prev, curr) {
    if(!curr) return prev
    const next = curr.next
    curr.next = prev

    // return reverse(prev = curr, curr = next)
    return reverse(curr, next)
  }
};
复制代码

注意递归的使用因为引入了调用栈来临时保存prev,事实上还是O(N)的复杂度

思考

在书写的时候,特意使用了一样的格式,可以看出迭代和递归的写法之间有很多相似之处

过程中通过画图可以让这个过程更加清晰

image-20210607212714446

END

欢迎关注 SedationH

尝试用JS更清晰的分析和实现算法题目~

分类:
前端
标签: