2013 腾讯实习生笔试题

题目:给定一个数组a[N],我们希望构造数组b[N],其中b[i]=a[0]*a[1]*...*a[N-1]/a[i]。
在构造过程:不允许使用除法;
要求:O(1)空间复杂度和O(n)时间复杂度;
除遍历计数器与a[N] b[N]外,不可使用新的变量(包括栈临时变量、对空间和全局静态变量等);
请用程序实现并简单描述。

解法1:

不能使用新的变量,利用收尾元素作为中间变量,第一次迭代b[0] = a[0], for (i 1->n-1)  b[i] = b[0],b[0] *= a[i]。
使b[] = {1, a[0],a[0]*a[1],...,a[0]*a[1]*a[2]*...*a[i-1]},第二次迭代 b[0] = 1, for (i n-1->1) b[i] *= b[0],
b[0] *= b[i];得到b数组。

代码:

//解法1
class Solution {
public:
    /**
     * @param A: Given an integers array A
     * @return: A long long array B and B[i]= A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1]
     */
    vector<long long> productExcludeItself(vector<int> &a) {
        // write your code here
        vector<long long> b;
        b.resize(a.size());

        b[0] = a[0];
        int num = a.size();
        for (int i=1; i<num; ++i) {
            b[i] = b[0]; /// 1 a[0...i-1]
            b[0] *= a[i];
        }
        b[0] = 1;

        for (int i=num-1; i>0; --i) {
            b[i] *= b[0];
            b[0] *= a[i];
        }
        return b;
    }
};

 解法2:

三次循环,第一次,b[0] = 1, for (int i=1; i<num; ++i) b[i] = b[i-1] * a[i-1];使b[] = {1, a[0], ...,a[0]*...*a[i-1]...}
第二次,a[n-1] = a[n-2], a[n-2] = a[n-1](异或实现交换), for (int i=n-3; i>=0; --i) a[n-1] *= a[i+1], a[i] = a[n-1], a[n-1] = a[i];
使a[] = {a[1]*...*a[n-1],.... , a[n-1]*a[n-2]*...*a[i+1],...}.第三次循环使b[i] *= a[i].

附代码:

//解法2
class Solution {
public:
    /**
     * @param A: Given an integers array A
     * @return: A long long array B and B[i]= A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1]
     */
    vector<long long> productExcludeItself(vector<long long> &a) {
        // write your code here
        vector<long long> b;
        b.resize(a.size());

        int num = a.size();

        b[0] = 1;

        for (int i=1; i<num; ++i) {
            b[i] = b[i-1] * a[i-1]; // b[i] = a[0...i-1]
        }

        a[num-2] = a[num-1] ^ a[num-2];
        a[num-1] = a[num-2] ^ a[num-1];
        a[num-2] = a[num-2] ^ a[num-1];

        for (int i=num-3; i>=0; --i) { // a[i] = a[num-1...i+1]
            a[num-1] *= a[i+1];

            a[i] = a[num-1] ^ a[i];
            a[num-1] = a[i] ^ a[num-1];
            a[i] = a[i] ^ a[num-1];
        }
        a[num-1] = 1;

        for (int i=0; i<num; ++i) {
            b[i] *= a[i];
        }
        return b;
    }
};

 解法2要求a数组也是long long 型。

参考链接:http://www.cnblogs.com/sooner/archive/2013/04/22/3036448.html                                

posted on 2017-01-14 17:33  小小八  阅读(160)  评论(0编辑  收藏  举报