Ruby codewars 上一道题的运行效率的问题

justvi · 2017年03月01日 · 最后由 justvi 回复于 2017年03月02日 · 1488 次阅读

在 codewars 上做一道题,题目如下:

Write function scramble(str1,str2) that returns true if a portion of str1 characters can be rearranged to match str2, otherwise returns false.
For example:
str1 is 'rkqodlw' and str2 is 'world' the output should return true.
str1 is 'cedewaraaossoqqyt' and str2 is 'codewars' should return true.
str1 is 'katas' and str2 is 'steak' should return false.
Only lower case letters will be used (a-z). No punctuation or digits will be included. Performance needs to be considered

我的解法如下:

s2.chars.reject {|c| s1.count(c) >= s2.count(c)}.empty?

虽然通过了测试,但是给出提示运行时间过长,看了别人的答案,有一个如下:

s2.chars.uniq.none? { |c| s1.count(c) < s2.count(c) }

这个是通过了测试,时间也没有问题的
这两种解法区别是在哪里呢?

假如 s2 = 'saaaaaaaaa',上面需要 count 10*2 次,下面只要 2*2 次。

可以大致分析两种方法的时间复杂的:

第一个方法

m = s1.length
n = s2.length
所以复杂度应该是 O(n * (m + n)) + O(n) = O(n^2) + O(nm)

第二个方法:

m = s1.length
n = s2.length

k = s2.uniq.length <= 26

O(n) + O(k *(m + n) + O(k) <= O(26 *(m + n)) + O(26) + O(n) = O(m+n) + O(n) = O(n) + O(m)

由于不是很了解细节,仅供参考。

saiga 回复

谢谢,看来要了解一下 map、reject、collect 等的实现方式了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号