找工作准备的面试题

本文涵盖了编程面试中的常见问题,包括删除整数数组中的冗余元素,寻找数组中和为特定值的数值对,解决连续正数序列问题,以及二叉树的层次遍历和比较。通过具体的解题思路和代码实现,帮助读者理解和掌握这些算法。
摘要由CSDN通过智能技术生成
master method:
T(n)=t(n/2)+lgn T(n)=O(lgn*lgn). n^lg1 = 0 < lgn << n^e for e > 0. the gap between case 2 and case 3. but the factor is lgn, then result is to take an extra logn.
see exercise 4.4-2
工作分配问题是个O(n!)复杂度不是O(n^n)复杂度
二分加线性是个好办法:先用二分查找缩小范围,在小范围内再使用线性查找。 比如100层鸡蛋问题:先用二分缩小范围,13,26,38.。。如果在某一层鸡蛋碎了,则可以使用另一个鸡蛋从上一次尝试成功那一层开始测试到鸡蛋碎了为止。最多8+12=20次。不是最优解,但是是一种方法。
analysis:
when we cannot determine the parameters to analyze the complexity try to find the worst case.
multiple thread algorithm:
T infinity: the critical path line: the longest path in the spawn graph where every node is the parent of another except the first node. that means the nodes in this path cannot be executed parallel. they must executed one by one. so T infinity = the length of the critical path line. P bar = T1/T infinity.

删除整形数组中的冗余整数

题目:给一个未排序的n个元素的数组,数组中所有的元素都在1到n之间,删除数组中所有冗余的数字

例如: {1,3,2,3,2,6,4,3}

删除冗余后数组: {1,2,3,4,6}

1. O(n)时间,O(n)空间:

用O(n)空间记录每个元素的出现次数

2. O(n)时间,O(1)空间

在有O(n)空间情况下,可以O(n)空间记录每个数字的出现情况,但是现在没有空间,则需要利用原有数组记录每个数字出现情况,同时为了不改变原有数组的信息,这里将原有数字设为原来数字的负绝对值。因为原来的数组里面是没有负数的,所以可以这样做。

seq[abs(seq[i])-1] = -abs(seq[abs(seq[i]-1)])

void removedup(int *a,int n)
{
    for(int i = 0;i<n;i++)

    {
        a[abs(a[i])-1]=-abs(a[abs(a[i])-1]);
    }

    for(int i = 0;i<n;++i)

    {
        if(a[i]<0)printf("%d\n",i+1);
    }
}

求整形数组中满足两数之和为sum的数值对

方法1:O(n^2)方法,两两相加
方法2:O(nlgn)排序后两边搜。
方法3:O(nlgn)排序后b[i]=sum-a[i],用二分查找找b[i]

PS:微软题目,用bitmap记录每个元素的出现情况(前提是每个元素出现一次,如果多次只能用bucket)
似乎快速找到数值对和为sum的方法只有bucket?
 

【题目35】和为n连续正数序列

//维持low,high两个变量,cnt=low+low+1+...+high
//从低到高
void findSeq1(int n){
    int low = 1;
    int high = 2;
    int cnt = low+high;
    while(low < high && high <=n/2+1){
        if(cnt == n){
            for(int i =low;i<=high;i++)printf("%d,",i);
            printf("\n");
            cnt -= low;
            cnt += high+1;
            low ++;
            high++;
        }
        else if(cnt > n){
            cnt -= low;
            low+=1;
        }
        else{
            high+=1;
            cnt+=high;
        }
    }
}

//从高到低
void findSeq(int n){
    int high =(n+1)/2;
    int low = high - 1;
    int cnt = low+high;
    while(low >= 1){
        if(cnt == n){
            for(int i =low;i<=high;i++)printf("%d,",i);
            printf("\n");
            cnt = cnt - high + low - 1;
            --high;
            --low;
        }
        else if(cnt > n){
            low-=1;
            cnt =cnt - high + low;
            high-=1;
        }
        else{
            low-=1;
            cnt+=low;
        }
    }
}



方法3. 假设 a + (a+1) + ... + b = n 是一个答案,则根据求和公式就是 (a + b) * (b - a

+ 1) / 2 = n, 则 (a+b)和 (b-a+1)分别是2N的一个因子,枚举其中一个,就可以判断求出第二个,

然后求出a和b了。时间复杂度是O(sqrt(n)).2n的因子范围肯定在[2,sqrt(2n)]之间。

   具体步骤:假设(b-a+1)是其中一个因子,可以通过2n%i == 0找到一个因子i,然后根据上面的

(a+b)*(b-a+1)/2 = n的公式可以推导出 2*a*i = 2n - i^2 + i, 因此只要判断a存在正整数解,就

可以知道满足上面条件的2n的另一个因子也是存在的。

  1. void ContinuousSequenceSum_2(int n)  
  2. {  
  3.     int nMax = (int)sqrt(2*n) + 1;  
  4.     int start,end,i;  
  5.     for(i = 2; i < nMax; i++)  
  6.     {  
  7.         if(2*n % i == 0)  
  8.         {     
  9.             int tmp = 2*n - i*i + i;  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值