用 JavaScript 完成链表操纵 - 02 Length & Count

TL;DR

盘算链表的长度和指定元素的反复次数。系列目次见 前言和目次

需求

完成一个 length() 函数来盘算链表的长度。

length(null) === 0
length(1 -> 2 -> 3 -> null) === 3

完成一个 count() 函数来盘算指定数字在链表中的反复次数。

count(null, 1) === 0
count(1 -> 2 -> 3 -> null, 1) === 1
count(1 -> 1 -> 1 -> 2 -> 2 -> 2 -> 2 -> 3 -> 3 -> null, 2) === 4

length

递归版本

递归是最有表达力的版本。思绪异常简朴。每一个链表的长度 length(head) 都即是 1 + length(head.next) 。空链表长度为 0 。

function length(head) {
  return head ? 1 + length(head.next) : 0
}

轮回版本 – while

链表轮回第一反应是用 while (node) { node = node.next } 来做,轮回外保护一个变量,每次自增 1 即可。

function lengthV2(head) {
  let len = 0
  let node = head

  while (node) {
    len++
    node = node.next
  }

  return len
}

轮回版本 – for

forwhile 在任何情况下都是能够交换的。我们能够用 for 轮回把变量初始化,节点后移的操纵都放到一同,简化一下代码量。注重由于 len 要在 for 外部作为返回值运用,我们只能用 var 而不是 let/const 声明变量。

function lengthV3(head) {
  for (var len = 0, node = head; node; node = node.next) len++
  return len
}

count

递归版本

length 思绪相似,区分只是递归时推断一下节点数据。

function count(head, data) {
  if (!head) return 0
  return (head.data === data ? 1 : 0) + count(head.next, data)
}

轮回版本

这里我直接演示的 for 版本,思绪相似就不多说了。

function countV2(head, data) {
  for (var n = 0, node = head; node; node = node.next) {
    if (node.data === data) n++
  }
  return n
}

参考资料

Codewars Kata
GitHub 的代码完成
GitHub 的测试

    原文作者:darkbaby123
    原文地址: https://segmentfault.com/a/1190000007689904
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞