这个2sum算法O(nlogn)怎么样?

时间:2017-01-15 16:26:04

标签: python runtime time-complexity

给定一个列表{ "lastModified": 1484495787000, "name": "Renascence", "realm": "Vek'nilash", "battlegroup": "Glutsturm / Emberstorm", "level": 25, "side": 1, "achievementPoints": 2565, "emblem": { "icon": 60, "iconColor": "ffb1b8b1", "iconColorId": 14, "border": 3, "borderColor": "ffffffff", "borderColorId": 14, "backgroundColor": "ff4f2300", "backgroundColorId": 44 }, "news": [{ "type": "itemLoot", "character": "Garnatou", "timestamp": 1484495940000, "itemId": 137514, "context": "challenge-mode", "bonusLists": [3415, 1507, 1813] }, { "type": "itemLoot", "character": "Belladona", "timestamp": 1484495820000, "itemId": 134203, "context": "world-quest-8", "bonusLists": [3473, 603, 1507, 3336] }, { "type": "itemLoot", "character": "Fireplume", "timestamp": 1484495760000, "itemId": 134204, "context": "world-quest-9", "bonusLists": [3474, 42, 604, 1507, 1674] }, { "type": "playerAchievement", "character": "Tsula", "timestamp": 1484495700000, "context": "", "bonusLists": [], "achievement": { "id": 6193, "title": "Level 90", "points": 10, "description": "Reach level 90.", "rewardItems": [], "icon": "achievement_level_90", "criteria": [{ "id": 5212, "description": "Reach level 90", "orderIndex": 1, "max": 90 }], "accountWide": false, "factionId": 2 } }, { "type": "itemLoot", "character": "Rockz", "timestamp": 1484495700000, "itemId": 143684, "context": "world-quest-8", "bonusLists": [3473, 1507, 3336] }, { "type": "itemLoot", "character": "Rukor", "timestamp": 1484495700000, "itemId": 113987, "context": "raid-mythic", "bonusLists": [567] }, { "type": "itemLoot", "character": "Trolljäger", "timestamp": 1484495520000, "itemId": 143684, "context": "world-quest-9", "bonusLists": [3474, 1507, 1674] }, { "type": "itemLoot", "character": "Rockz", "timestamp": 1484495400000, "itemId": 129067, "context": "", "bonusLists": [1794, 1735] }, { "type": "itemLoot", "character": "Angël", "timestamp": 1484495340000, "itemId": 137531, "context": "dungeon-mythic", "bonusLists": [1727, 1808, 1492, 1813] }, { "type": "itemLoot", "character": "Rockz", "timestamp": 1484495340000, "itemId": 134316, "context": "world-quest-9", "bonusLists": [3474, 1507, 1674] } 和一个int L,我必须找出列表中是否有两个元素,加起来为c(2Sum问题)。我提出了以下算法:

c

现在我发现它在 O(n log n)中运行,因为排序需要 O(n log n)操作。 “扫描”应该采取 O(n)动作。怎么来的?

我认为最糟糕的情况是def tsum(L,c): a=sorted(L) b=sorted(L,reverse=True) for kleineZahl in a: for großeZahl in b: sum=kleineZahl+großeZahl if sum>c: continue elif sum==c: return(True) elif sum<c: break return(False) 。运行时如何不是n / 2 * n / 2,所以 O(n 2

2 个答案:

答案 0 :(得分:1)

您在上面讨论的算法确实具有 O(n 2 的时间复杂度。实际上,这里不需要先对元素进行排序。但是,你可以实现一个更聪明的方法:首先对列表进行排序,然后保留两个指针:rightrightright在您的列表中从left移动到a[left]+a[right] >= sum,约束始终保持True。如果您获得了匹配,则会返回left,如果right经过False,我们就知道没有此类匹配,我们会返回left,因为最多right并且def tsum(L,c): a=sorted(L) left = 0 right = len(L)-1 while left < right: right1 = right while a[left]+a[right1] > c: right1 -= 1 if a[left]+a[right1] == c: return True elif right1 < right: right = right1+1 left += 1 return False 执行 O(n)步骤,时间复杂度为 O(n),但排序步骤使其 O(n记录n)。因此更智能的算法是:

{{1}}

不同之处在于您不必从 far -right检查数组中的某个点,您只需从上一次迭代的结束处开始。

答案 1 :(得分:0)

你可以通过完全删除内循环来使它成为O(n)。 我将依赖基本的数学和哈希映射(字典)。 请注意,hashmap搜索应该在恒定时间O(1)

中进行

下面的代码是用Swift编写的,但你可以轻松地将它翻译成Python。 请注意,它返回所有元素的索引,其总和等于'sum':

func findTwoSum(_ array: [Int], sum: Int) -> [(Int, Int)] {
    var result = [(Int, Int)]()

    var diffs = Dictionary<Int, Int>()

    for i in 0..<array.count {
        let val = array[i]

        // if the number is already in the dict, we've found the pair
        // since diff + val == sum
        let diff = sum - val
        if let foundIndex = diffs[diff]  {
            result.append(contentsOf: [(foundIndex, i), (i, foundIndex)])
        } else {
            // store the value in the dict
            diffs[val] = i
        }            
    }

    return result
}