一道Javascript面试题,去除数组中的重复数字,大家看看我的做法是否正确

去除数组中重复数字。网上这样的题目解答很多,但是我感觉面试官要的最好最正确的答案是不开辟新内存及最优化的算法。

思想如下:

把指针分别指向数组头和尾,如果想等j--,i和{i+1,j}之间的数据做比较,如果想等和j位置上的数据做交换,如果j位置上的数字和i想等j--,直到和不想等j位置上的数据做交换,i++继续循环,当 i=j 时结束,见下图:
第一次:[1,47,89,1,18,1,47,6,90,77,50,88,89,89,0,6,1]
        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

代码如下:

function f(arr) {
            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]));

原文地址:https://www.cnblogs.com/KangC/p/2243078.html