我有一个长度为A
的数组n
,其中包含长度为3的字符串。我想构建一个数组B
,其中A
中的每个字符串都被其等级替换在A
中关于词典排序。 (请注意A
可能有重复项,因此B
也可能有重复项。)
假设JavaScript A.sort()
及时A
执行基数排序O(n)
,我如何在B
时间O(n)
内构建A
}?
示例:如果A
['abb', 'ada', 'bba', 'bba', 'dab', 'bad']
然后B
[1, 2, 4, 4, 5, 3]
(注意:您可以假设阵列分配需要一段时间。)
答案 0 :(得分:2)
这是我能想到的最快的事情......
function cheese(a){
var b = [];
var c = {};//hash references to make lookups really fast
var d = [];//desired output
for(var i = 0; i < a.length; i++)
{
if(!c[a[i]])
b.push(a[i]);
c[a[i]] = true;
}
b.sort();
for(i = 0; i < b.length; i++)
{
c[b[i]] = i;
}
for(i = 0; i < a.length; i++)
d.push(c[a[i]] + 1);
return d;
}
答案 1 :(得分:0)
我会尝试,但我对此感到不自信:
无论如何,它似乎给出了理想的结果,所以让我们走吧:
Array.prototype.getLexicoGraphic = function() {
var result = [],
sorted = this.slice(0).sort();
for(var i = 0; i < sorted.length; i ++) {
result[i] = sorted.indexOf(this[i]) - (i - sorted.indexOf(sorted[i])) + 1;
}
return result;
}
答案 2 :(得分:0)
构造辅助数组,该数组将包含该值及其原始索引 - O(n)
。
[[0, 'abb'], [1, 'ada'], [2, 'bba'], [3, 'bba'], [4, 'dab'], [5, 'bad']] // Stored as 'foo' in the following examples
使用comparator function对新创建的数组进行排序 - 根据您的假设O(n)
(但我对此表示怀疑)。
foo.sort(function (a, b) { return a[1].localeCompare(b[1]); });
迭代排序后的数组并在路上创建排名数组 - O(n)
。
var last = null, rank = 0, result = [], i;
for (i = 0; i < foo.length; i++) {
result[foo[i][0]] = (last === null || last.localeCompare(foo[i][1]) != 0) ? ++rank : rank;
last = foo[i][1];
}
享受您的result
。
更新另一种方法是通过带索引的关联数组:
{ 'abb': [0], 'ada': [1], 'bba': [2, 3], 'dab': [4], 'bad': [5] }
然后你可以创建一组键(因此是唯一值),对它进行排序并根据它构建你的排名。
答案 3 :(得分:0)
var A = ['abb', 'ada', 'bba', 'bba', 'dab', 'bad'];
var B = [];
// Assuming slice(0) is O(n)
var Ap = A.slice(0);
var H = [];
var N = A.length;
var i, index;
// O(n)
A.sort();
// O(n)
for (index = 1, i = 0; i < N; i++) {
// Assuming that H[A[i]] is O(1)
if (!H[A[i]]) {
H[A[i]] = index;
index++;
}
}
// O(n)
for (i = 0; i < N; i++) {
B[i] = H[Ap[i]];
}
console.log(B);
// 4 * O(n) === O(n)
答案 4 :(得分:0)
您可以在O(n)时间
中创建一个序数数组var a = ...;
var ranks = [];
for (var i = 0; i < a.length; ++i) { ranks[i] = i; }
然后,您可以定义一个比较器,通过比较索引字符串
来比较整数function cmp(i, j) {
return a[i] < a[j] ? -1 : a[i] = a[j] ? 0 : 1;
}
由于字符串是恒定长度,因此每次比较都需要恒定的时间。
然后在ranks
上执行自定义排序,而不是使用您规定的cmp
需要线性时间。这将产生b
。
如果您需要a
的排序版本,则可以在线性时间内从a
和ranks
重新构建它。
var aSorted = [];
for (var i = 0; i < a.length; ++i) {
aSorted[i] = a[ranks[i]];
}