【问题标题】:Hash Tables: Ransom Note - Hacker Rank in Swift Timed Out哈希表:赎金票据 - Swift 中的黑客排名超时
【发布时间】:2019-02-21 14:15:48
【问题描述】:

我的代码没问题,但是在一些测试用例上总是抽空,有什么改进的方法吗?我的猜测是 indexOf 函数耗时太长。

func checkMagazine(magazine: [String], note: [String]) -> Void {
var mutableMag = magazine
if note.count > mutableMag.count {
    print("No")
    return
}
for word in note {
    if let index = mutableMag.index(of: word) {
        mutableMag.remove(at: index)
    } else {
        print("No")
        return
    }
}
print("Yes") }

请在此链接中找到挑战:https://www.hackerrank.com/challenges/ctci-ransom-note/problem

【问题讨论】:

  • 您已经得到了很好的答案,但请注意,这也是codereview.stackexchange.com 上的一个好问题。他们有专门的标签“programming-challenge”和“time-limit-exceeded”来解决此类问题。

标签: arrays swift dictionary swift3 hashmap


【解决方案1】:

通过所有测试的一种可能的解决方案是使用NSCountedSet 来存储笔记和杂志中的单词,并将note 中每个单词的计数与magazine 中该单词的计数进行比较,如果有的话在magazine 中较低,提前返回并打印No

我还建议更改函数签名以返回 Bool 值,即使黑客等级生成的函数原型返回 Void。最好把checkMagazine做成一个纯函数,不要在里面做任何I/O操作。

func checkMagazine(magazine: [String], note: [String]) -> Bool {
    let magazineWords = NSCountedSet(array: magazine)
    let noteWords = NSCountedSet(array: note)
    for noteWord in noteWords {
        if magazineWords.count(for: noteWord) < noteWords.count(for: noteWord) {
            return false
        }
    }
    return true
}

那你只需要把生成的代码的结尾改成如下:

let magazineWorks = checkMagazine(magazine: magazine, note: note)
if magazineWorks {
    print("Yes")
} else {
    print("No")
}

【讨论】:

  • 很好的解决方案,谢谢。一个问题,我的代码的问题是indexOf函数?
  • @ArildoJunior 基本上是的。 Array.index(of:) 的时间复杂度是线性的 (O(n)),由于您在循环中为数组的所有元素调用 index(of:),因此算法的时间复杂度是二次的 (O(n^2))。另一方面,NSCountedSet.count(for: ) 具有恒定的时间复杂度(O(1)),因此我的答案中的算法具有线性时间复杂度。
【解决方案2】:
func checkMagazine(magazine: [String], note: [String]) -> Void {
    var notesDictionary : [String : Int] = [:]
    var magazineDictionary : [String : Int] = [:]

    var canMakeRansom = true

    for n in note {
        var count = notesDictionary[n] ?? 0
        count += 1
        notesDictionary[n] = count
    }

    for n in magazine {
        var count = magazineDictionary[n] ?? 0
        count += 1
        magazineDictionary[n] = count
    }

    for note in notesDictionary {
        if note.value > magazineDictionary[note.key] ?? 0 {
            canMakeRansom = false
        }
    }
    print(canMakeRansom ? "Yes" : "No")
}

这是解决此问题的另一种方法。 我认为这会以某种方式完成 NSCountedSet 本身所做的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 2023-03-27
    • 2023-02-11
    • 1970-01-01
    相关资源
    最近更新 更多