我正在尝试练习面试,并在线发现了一个挑战,即编写一个函数,该函数将获取数组,并且只返回数组中仅存在一次的值,并按顺序返回这些值。例如,数组[1,3,5,6,1,4,3,6]应返回[4,5]。
我有一个传递测试的脚本,但是有些测试运行得太慢了。我错了吗?是否有一些基本方法可以加快速度?该脚本以findTheNumbers开头,a是数组输入:
function findTheNumbers(a) {
var retVal = [];
var nonUnique = [];
for (var i = 0; i < a.length; i++){
var isUnique = true;
if (i != 0){
for (var j = 0; j < nonUnique.length; j++){
if (a[i] == nonUnique[j]){
isUnique = false;
break;
}
}
}
if (isUnique){
for (var k = 0; k < a.length; k++){
if (a[i] == a[k] && i != k){
isUnique = false;
nonUnique.push(a[i]);
break;
}
}
}
if (isUnique){
retVal.push(a[i]);
if (retVal.length == 2){
break;
}
}
}
retVal = sortArrayOfLengthOfTwo(retVal);
return retVal;
}
function sortArrayOfLengthOfTwo(array){
var retVal = [];
if (array[0] > array[1]){
retVal.push(array[1]);
retVal.push(array[0]);
} else {
retVal = array;
}
return retVal;
}
更新 -
不确定最佳位置在哪里,但这是我的新版本基于已接受答案的提示(其工作速度更快):
function findTheNumbers(a) {
var retVal = [];
var dict = {};
for (var i = 0; i < a.length; i++){
dict[a[i]] = 1 + (dict[a[i]] || 0);
}
for (var key in dict){
if (dict[key] == 1){
retVal.push(parseInt(key));
}
}
return retVal;
}
答案 0 :(得分:5)
当程序太慢时,经验法则是
在您的情况下,您解析整个数组n次,即复杂度为o(n ^ 2)。只需一个完整的解析,每个元素的计数字典就可以完成相同的操作。
修改新算法
你的新算法非常好。为了你的采访,我有一些评论:
var
,您应该考虑尽可能使用const
,而let
否则以下是我实施它的方式:
function findTheUniqueNumbers(a) {
const numberCounts = {} // I prefer "new Map()" on recent env.
a.forEach( function(e) {
const previousCount = numberCounts[e] || 0
numberCounts[e] = previousCount + 1
} )
return Object.keys(numberCounts)
.filter( function(e) {
return numberCounts[e] === 1
} )
}
const uniqueNumber = findTheUniqueNumbers([1, 3, 5, 6, 1, 4, 3, 6])
console.log(uniqueNumber)