【问题标题】:Find the parity outlier Javascript查找奇偶校验异常值 Javascript
【发布时间】:2020-01-02 00:21:31
【问题描述】:

当答案仅为负奇数时,我的函数失败(返回未定义)。 否则它工作。 有谁知道为什么?

说明:

给你一个包含整数的数组(长度至少为 3,但可能非常大)。数组要么完全由奇数组成,要么完全由偶数组成,除了单个整数 N。编写一个将数组作为参数并返回此“异常值”N 的方法。

我的代码:

function findOutlier(integers) {
  let binary = integers.map((int, i) => int % 2);
  let count = 0;
  for (let i = 0; i < binary.length; i++) {
    if (binary[i] == 0)
      count++;
  }
  if (count > 1) {
    return integers[binary.indexOf(1)]
  } else {
    return integers[binary.indexOf(0)]
  }
}

【问题讨论】:

  • 在失败的情况下,你为integers传递了什么?
  • 最好的办法是使用浏览器和/或 IDE 中内置的调试器,并在返回语句上设置断点。可能最好将调用拆分为indexOf,这样您就可以找出哪个没有返回您所期望的(它似乎返回-1,当然,integers[-1] 是@ 987654326@).
  • 值得注意的是,您的函数最多可以遍历数据三次(map 一次完整遍历,for 循环的另一次完整遍历,@987654329 中的第三次可能部分遍历@),即使作业说 "...but could be very large..." 这表明您可能希望尽可能避免这种情况。但是,永远不需要到离群值之外超过两个地方才能知道它在哪里(如果离群值是第一个条目,那就是这样),并且在大多数情况下,你一遇到它就会知道它在哪里(因为您会事先至少看到两个赔率或偶数)。

标签: javascript arrays


【解决方案1】:

JavaScript % 运算符在某些情况下会返回负数(当左侧为负数而右侧为正数时)。因此,您的 .indexOf(1) 不会在数组中找到 -1

您可以在.map() 回调中修复它,方法是使用(i) =&gt; i &amp; 1 直接检查最低有效位。

如果是我,我会将赋值中关于数组可能“非常大”的警告解释为应该最小化迭代的警告。因此,我很想以不同的方式处理这个问题。一旦您看到多个偶数或多个奇数,您可以假设第一个不符合模式的数字是异常值。 (哦,我突然想到,数组总是至少有 3 个元素的规定是对所需解决方案的另一个提示:您只需要检查前 3 个元素来确定输入数组是几乎全偶数还是几乎都是奇怪的。)

所以可能是这样的:

function outlier(integers) {
  function par(i) { return i & 1; }

  let parity = par(integers[0]);
  if (parity != par(integers[1])) {
    if (parity == par(integers[2]))
      // [0] and [2] are the true parity so [1] is the outlier
      return integers[1];

    // [1] and [2] are the true parity so [0] is the outlier
    return integers[0];
  }
  return integers.find((i) => par(i) != parity);
}

【讨论】:

  • 例如,如果integers 之一是-3 或任何其他奇数负数。
  • 很好的答案。我不熟悉(i) =&gt; i &amp; 1 语法。这是返回 2 个值吗?你能指出我正确的方向来阅读这个吗?
  • @PDJ &amp;(单个&amp;,而不是&amp;&amp;)是二元与运算符。通过将其与右侧的 1 一起使用,结果将是 0 或 1,因为只有当左侧的最低位也是 1 时,AND 才会给出 1。因此 1 表示它是奇数,而 0 表示它是甚至。
【解决方案2】:

当您在% 的左侧使用负数时,Javascript % 将返回负数。

例如-3%2 = -1

要处理这种情况,您可以更改代码:

function findOutlier(integers) {
  let binary = integers.map((int, i) => Math.abs(int) % 2 );
  let count = 0;
  for (let i = 0; i < binary.length; i++) {
    if (binary[i] == 0)
      count++;
  }
  if (count > 1) {
    return integers[binary.indexOf(1)]
  } else {
    return integers[binary.indexOf(0)]
  }
}

这可行,但有更好的方法来解决上述问题,时间复杂度更高。如其他答案中所述(您只需要 3 次通过即可确定异常值是偶数还是奇数)

【讨论】:

    【解决方案3】:

    您可以获取一个对象来存储奇数 (false) 或偶数 (true) 值的前两个索引,并在找到至少一个和另一个类型中的一个时提前退出。

    const isEven = value => value % 2 === 0;
    
    function find(array) {
        var indices = { true: [], false: [] },
            i, key;
            
        for (i = 0; i < array.length; i++) {
            key = isEven(array[i]);
            if (indices[key].length < 2) indices[key].push(i);
            if (indices.true.length > 1 && indices.false.length === 1) return indices.false[0];
            if (indices.false.length > 1 && indices.true.length === 1) return indices.true[0];
        }
        return indices;
    }
    
    console.log(find([1, 0, 0]));
    console.log(find([0, 1, 0]));
    console.log(find([0, 0, 1]));
    console.log(find([0, 1, 1]));
    console.log(find([1, 0, 1]));
    console.log(find([1, 1, 0]));

    【讨论】:

      猜你喜欢
      • 2019-09-18
      • 1970-01-01
      • 2019-10-28
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 1970-01-01
      • 2015-06-29
      • 2013-06-25
      相关资源
      最近更新 更多