一道Javascript面试题,去除数组中的重复数字,大家看看我的做法是否正确
思想如下:
i j
第二次:[1,47,89,6,18,0,47,6,90,77,50,88,89,89,1,1,1]
i j
第三次:[1,47,89,6,18,0,89,6,90,77,50,88,89,47,1,1,1]
i j
第四次:[1,47,89,6,18,0,88,6,90,77,50,89,89,47,1,1,1]
i j
完成: [1,47,89,6,18,0,88,6,90,77,50,89,89,47,1,1,1]
ij
代码如下:
var i = 0, j = arr.length - 1;
while (i != j) {
for (; i < j; i++) {
for (var z = i+1; z <= j; z++) {
if (arr[i] == arr[z]) {
while (arr[z] == arr[j]) { // 去除j位置上和当前比较数想等的数字。
j--;
arr.pop();
}
arr[z] = arr[j] ^ arr[z];
arr[j] = arr[j] ^ arr[z];
arr[z] = arr[j] ^ arr[z];
j--;
arr.pop();
}
}
}
}
return arr; // 不用pop这里可以用arr.slice(0,i);
}
alert(f([1,47,89,1,18,1,47,6,90,77,50,88,89,89,0,6,1]));
但上述方法比较的次数是 n2-1次 ,显然算法不是很优化。
算法优化
function f(arr) {
var nArr = new Array();
nArr.push(arr.pop());
while(arr.length)
nArr = t(nArr, arr.pop());
return nArr;
}
function t(arr, v) {
var len = arr.length;
if (len == 1 && arr[0] == v)
return arr;
else if (len == 1 && arr[0] < v) {
arr.push(v);
return arr;
}
else if (len == 1 && arr[0] > v)
return [v].concat(arr);
var i = Math.ceil(len / 2);
if (arr[i] > v) // 大于进入左叶比较
return t(arr.slice(0, i), v).concat(arr.slice(i, arr.length));
if (arr[i] < v)// 小于进入右叶比较
return arr.slice(0, i).concat(t(arr.slice(i, arr.length), v));
return arr;
}
alert(f([3,2,1,2,11,3,3,77,88,99,99,100,3,77]));