加快Swift CodeFight挑战赛

时间:2017-07-22 03:13:42

标签: swift algorithm

每个Codefighters:

注意:编写具有O(n)时间复杂度和O(1)额外空间复杂度的解决方案,因为这是您在真实访谈期间要求做的事情。

给定一个仅包含1到a.length范围内的数字的数组a,找到第二个匹配项具有最小索引的第一个重复数字。换句话说,如果有多于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毫秒。我坚持我还能做些什么。有什么提高速度的想法吗?

func firstDuplicate(a : [Int]) -> Int {
var duplicateIndexArray = [Int]()
for firstIndex in 0..<a.count {

    for secondIndex in 0..<a.count {

        if a[firstIndex] == a[secondIndex] && firstIndex != secondIndex {
            print(firstIndex, secondIndex)
            if !(duplicateIndexArray.contains(firstIndex)){
                duplicateIndexArray.append(secondIndex)
                break
            }
        }
    }
}

// Check for duplicacy
if duplicateIndexArray.count > 0 {
    print(duplicateIndexArray)
    return a[duplicateIndexArray.min()!]
}
return -1

}

3 个答案:

答案 0 :(得分:0)

O(n)时间部分很容易,但O(1)额外空间有点棘手。通常,哈希集(或您的情况下的位数组)可用于检查数字是否出现多次,但这需要额外的O(n)空间。对于O(1)额外空间,我们可以将源数组本身用作位数组,使其中的一些数字为负数。

例如,如果数组中的第一个数字是3,那么我们将位置3-1的数字设为负数。如果数组中的其他数字之一也是3,我们可以检查位置3-1的数字是否为负数。

我对Swift没有任何经验,所以我会尝试在pseudocode中编写一个函数:

function firstDuplicate(a)
    result = -1

    for i = 0 to a.count - 1
         if a[abs(a[i])-1] < 0 then 
             result = a[i] 
             exit for loop
         else
             a[abs(a[i])-1] = -a[abs(a[i])-1]

    // optional restore the negative numbers back to positive
    for i = 0 to a.count - 1
        if a[i] < 0 then 
            a[i] = -a[i]

    return result

答案 1 :(得分:0)

替换此行

for secondIndex in 0..<a.count

for secondIndex in firstIndex..<a.count

无需双重检查

所以你的最终代码是

func firstDuplicate(a : [Int]) -> Int {
    var duplicateIndexArray = [Int]()
    for firstIndex in 0..<a.count {

        for secondIndex in firstIndex..<a.count {

            if a[firstIndex] == a[secondIndex] && firstIndex != secondIndex {
                print(firstIndex, secondIndex)
                if !(duplicateIndexArray.contains(firstIndex))
                {
                    duplicateIndexArray.append(secondIndex)
                    break
                }
            }
        }
    }

    // Check for duplicacy
    if duplicateIndexArray.count > 0
    {
        print(duplicateIndexArray)
        return a[duplicateIndexArray.min()!]
    }
    return -1
}

答案 2 :(得分:0)

func firstDuplicate(input: [Int]) -> Int{
    var map : [String : Int] = [:]
    var result = -1
    for i in 0 ..< input.count {
        if map["\(input[i])"] != nil {
            result = i
            break
        }
        else {
            map["\(input[i])"] = i
        }
    }
    return result
}