我有一袋字符串,我想要映射到另一个包,这样重复的内容会在发现后用该成员的多样性进行后置,同时保留排序。例如,给定:
["a", "b", "a", "c", "b", "a"]
我想:
["a", "b", "a #1", "c", "b #1", "a #2"]
(由于这是部分订购的行李,[“a”,“a#1”,“a#2”,“b”,“b#1”,“c”]不是有效的结果。 )
一个明显的解决方案构建了多重集(对于上面的示例,{a:3,b:2,c:1})并且在时间上是O(n),在空间中是O(n):
function mark(names) {
var seen = {};
for (var i = 0; i < names.length; i++) {
var name = names[i];
if (name in seen) {
names[i] = name + ' #' + seen[name];
seen[name]++;
} else {
seen[name] = 1;
}
}
return names;
};
我的问题:是否存在一个具有更好整体复杂性的非显而易见的解决方案?或者换句话说,有什么其他方法可以实现这个算法,以便更好地处理最坏的情况,当包实际上是一组(非常大的尺寸)?
如果删除了poset要求,还有其他方法吗?
答案 0 :(得分:1)
你想降低哪种复杂性?没有办法让时间少于O(n),因为你至少要吐出一个很长的列表,这意味着你至少要进行n次操作。你也不能低于O(n)总空间,因为你的输出将是n长。
“see”的工作空间是O(m),其中m是数组中唯一条目的数量,如果你使用了hashmap或simliar。因为m <= n,你仍然不能低于O(n)。
如果您正在寻找节省空间并且输入有序,您可以使用O(1)工作空间进行计数,直到您看到一个新角色并重置您的计数器。再次,它不会让你低于O(n),包括你的输出列表,但那是不可能的。