为codefighters javascript firstDuplicate()函数加速此代码

时间:2017-06-24 03:50:17

标签: javascript

每个Codefighters:

  

注意:写一个O(n)时间复杂度和O(1)附加的解决方案   空间复杂性,因为这是你要求你做的事情   真实的采访。

     

给定一个数组a,它只包含1到1之间的数字   a.length,找到第二个的第一个重复数字   发生具有最小指数。换句话说,如果还有更多   超过1个重复的数字,返回第二个数字   出现的索引小于另一个出现的索引   号码呢。如果没有这样的元素,则返回-1。

     

实施例

     

对于a = [2,3,3,1,5,2],输出应为firstDuplicate(a)=   3。

     

有两个重复:数字2和3.第二次出现3   索引比第二次出现的索引小2,所以   答案是3。

     

对于a = [2,4,3,5,1],输出应为firstDuplicate(a)= -1。

所以这就是我想出来的。它工作但最终测试失败,因为它运行超过4000毫秒。我不知道我还能做些什么。有什么提高速度的想法吗?

function firstDuplicate(a) {
    var test   = [],
        lowest = undefined;

    for (var i=0; i<a.length; i++) {
        if (test.indexOf(a[i]) > -1) {
            lowest = lowest || i;
            if (i < lowest) {
                lowest = i;
            }
        }
        else {
            test.push(a[i]);
        }
    }

    return lowest ? a[lowest] : -1;
}

这是我的第二次尝试,但在最后一次测试中仍未通过......

function firstDuplicate(a) {
    var low = undefined,
        last = -1;

    for (var i=0; i<a.length; i++) {
        last = a.lastIndexOf(a[i])
        if (last > i && (low === undefined || last < low)) {
            low = last;
        }
    }

    return low !== undefined ? a[low] : -1;
}

4 个答案:

答案 0 :(得分:8)

要求提供了如何解决这个问题的线索。数组中包含的数字集必须与以下标准匹配:

  

只有1到a.length范围内的数字

换句话说,只有小于或等于数组长度的正数。如果数组包含十个数字,则它们都不会大于10.

凭借这种洞察力,我们有办法跟踪我们已经看过的数字。我们可以将数字本身视为数组的索引,修改该索引处的元素(在这种情况下使其为负数),如果我们遇到相同的数字并且该索引处的元素小于零,那么我们就知道了已经看过了。

&#13;
&#13;
console.clear()
const test1 = [2, 3, 3, 1, 5, 2]
const test2 = [2, 4, 3, 5, 1]


function firstDuplicate(a) {
  for (let i of a) {
    let posi = Math.abs(i) - 1
    if (a[posi] < 0) return posi + 1
    a[posi] = a[posi] * -1
  }

  return -1
}

console.log(firstDuplicate(test1))
console.log(firstDuplicate(test2))
console.log(firstDuplicate([2,2]))
console.log(firstDuplicate([2,3,3]))
console.log(firstDuplicate([3,3,3]))
&#13;
&#13;
&#13;

原始不正确答案

跟踪已经看过的数字并返回之前看过的第一个数字。

&#13;
&#13;
console.clear()
const test1 =   [2, 3, 3, 1, 5, 2]
const test2 = [2, 4, 3, 5, 1]

      
function firstDuplicate(a){
  const seen = {}
  for (let v of a){
    if (seen[v]) return v
    seen[v] = v
  }
  
  return -1
}

console.log(firstDuplicate(test1))
console.log(firstDuplicate(test2))
&#13;
&#13;
&#13;

正如评论中所指出的,这个答案需要额外的O(n)空间,而不是O(1)额外的空间。

答案 1 :(得分:3)

我们将利用数组@Override public void onCreate(Bundle savedInstanceState) { ... ImageView imageView = (ImageView) findViewById(R.id.my_image_view); GlideApp.with(this).load("http://i.imgur.com/qFeBmOF.png").into(imageView); } 仅包含1到a 范围内的数字这一事实,以便记住通过反转看到的值数组中该位置的任何符号。

&#13;
&#13;
a.length
&#13;
&#13;
&#13;

答案 2 :(得分:1)

通过测试的Python 3版本。

def firstDuplicate(a):
    oldies={}
    notfound=True
    for i in range(len(a)):
        try:
            if oldies[a[i]]==a[i]:
                notfound=False
                return a[i]     
        except:
            oldies[a[i]]=a[i]
    if notfound:
        return -1  

答案 3 :(得分:0)

您在两个示例中都在迭代n次。

如果数组长度为200,000,000并且在索引3处找到第一个副本,该怎么办?循环仍然不必要地运行200,000,000次。

所以我们的想法是在找到第一个副本后突破循环。 您可以使用breakreturn