2 回答
TA贡献1799条经验 获得超9个赞
除了奥莱的回答,你还需要考虑一些“微”优化:
我怀疑大部分时间都会花在执行这个循环上:
for(int k=0;k<s.substring(0,qq-1).length();k++){ if((s.substring(0,(qq-1)).charAt(k)==someChar)) count[j]++; }
让我们看几个方面:
k<s.substring(0,qq-1).length()
创建一个子字符串,以便它可以计算出它的长度。但是我们知道那个长度是多少:qq
!qq
因此,您无缘无故地创建了一个新字符串并复制了字符。效率低下。无意义。s.substring(0,(qq-1)).charAt(k)==someChar
创建另一个字符串,然后获取它的k
第 th 个字符。但是k
子字符串的第 th 个字符也是k
原始字符串的第 th 个字符s
。(想想看!)所以,再一次创建子串是没有意义的。那些不必要的计算都重复了
qq
多次。这是相同的(不必要的)计算完成2 x qq
时间。
注意:此分析不考虑您的代码是否正确或算法是否最优。这纯粹是关于微观效率。你所做的是将O(N^2)
算法变成O(N^3)
算法......由于不必要的子字符串创建。
TA贡献1821条经验 获得超6个赞
对于长字符串(最多 500000 个字母)和许多查询(最多 10000 个)的有效解决方案,您需要以某种方式预处理字符串数据,以便之后您可以快速处理每个查询。我建议对于 26 个可能的小写字母(问题明确表示“a”-“z”)中的每一个,找到第 1、2、3 次出现的位置等,并将它们填充到数组或列表中。然后对于每个查询,在数组中进行二进制搜索以查找您作为输入获得的位置。然后找到的数组索引会告诉你答案。这会将您的时间复杂度从O(s^2 * q)降低到O(s + q * log(s))。
如果您不知道二进制搜索,请查找它。或者使用 aMap<Integer, Integer>
而不是数组或列表。
更高效的是,构建一个与字符串长度相同的数组,并在每个索引中存储关于该索引的查询的答案。我相信这可以用复杂度O(s + q)来实现。
添加回答
举报