2010笔面试专栏二:数组

1、google面试题:

(1)一个数组存放了2n+1个整数,其中有n个数出现了2次,1个数出现了1次,找出出现1次的数是多少?(可能不少人遇到过,但是当时我是第一次遇到,我把我的经过给大家讲一遍)

  A. 由于想在最短时间内解决,我首先想到最简单的办法,使用映射统计的办法,借助辅助数组(长度为n+1,元素为一结构体(包含数值和个数两个成员))进行计数,但是时间复杂度为O(n*n),空间复杂度为O(n+1),面试官让我改进。

  B. 接着我在纸上划划,发现如果排序后重复2次的都排在一起, 如:(3,3),(5,5),(18,18),(26,57),57

  那么只需要每两两考察是否一样,如果不一样(蓝色标志)则只出现1次的数(26)必定出现在左边。解法:使用快速排序对数组进行排序,再两两元素进行比较,相等则继续前面操作,否则输出左边的元素值。 时间复杂度为O(nlogn)。

      面试官继续询问有没更好的办法,我想时间复杂度一定是线性的O(2n+1)

  C. 当时我没能想出来,后来回去后找到了解法:对数组A的所有元素做异或,即A[0]异或A[1]…… 异或A[2n]结果就是答案,理由:相同的数异或等于0,而0和任何数以后等于任何数,且异或运算可交换。

4、百度笔试:给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。要求:空间复杂度O(1)。

  解法1:使用插入排序的思想,假设当前考察的元素之前的都已经符合左边为奇数,后边为偶数的条件,那么如果当前元素为偶数则不做任何操作继续考察下一元素,如果当前元素为奇数则向前寻找第一个奇数a(注意是奇数,偶数跳过),把该奇数a后面到当前元素前面的所有元素都后移一位,把当前元素插入该奇数a后一位置。重复以上步骤直到所有元素考察完毕。  

void ArrangeInsert1(int A[],int n)
{
    int key=0;
    for(int i=1;i<n;i++)
    {
        key=A[i];
        int j=i-1;
        while(j>=0)
        {
            if(key%2==1)
            {
                if(A[j]%2==1)
                {
                    break;
                }
            }
            else
            {
                break;
            }
            j--;
        }
        for(int m=i-1;m>j;m--)
        {
            A[m+1]=A[m];
        }
        A[j+1]=key;
    }
}


 

 

转载自:http://kb.cnblogs.com/page/81013/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值