[微软面试100题]11-20

第十一题:求二元树中两个节点最远的距离

方法:使用递归函数求左右子树的深度。左子树深度+右子树深度=最大距离。
int BinaryTreeNode::getDeep(int floor){//(也是形参传递参数,返回值传递结果)
    int leftDeep=this->m_pLeft!=NULL ? this->m_pLeft->getDeep(floor+1) : floor;
    int rightDeep=this->m_pRight!=NULL ? this->m_pRight->getDeep(floor+1) : floor;
    return leftDeep>rightDeep ? leftDeep : rightDeep;
}

第十二题:求1+2..+n。要求不能使用* / if for while switch case ? :

使用了if:递归法
int helper(int i,int n){
    if(i<n){
        return i+helper(i+1,n);
    }
    return n;
}
int sumToN(int n){
    return helper(1,n);
}

方法1:利用静态变量记录sum,在构造函数里面累加,然后new n个对象

方法2:使用函数指针数组。把bool转化为0 1来代替if
int f1(int i,int n){
    return i+helper(i+1,n);
}
int f2(int i,int n){
    return n;
}
int helper(int i,int n){
    int (*p[2])(int i,int n);//定义函数指针数组
    p[1]=f1;
    p[0]=f2;
    return p[i<n](i,n);//把bool转化为0 1来代替if
}

第十四题:给定一个升序数组。找出两个元素使他们之和等于一个给定的数

使用两个指针从头和从尾逼近。如 2 4 6 8 9求和为8的。当头指针为2时,结果一定在>=8-2=6,就是在9~6之间。如果9~6之间没符合的,就是头指针2不是答案。则头指针变成4. 则此时结果在6~4之间。如此类推。每个头指针对应的末指针区间都不重复的。因此O(n)即可。
也就是说头尾指针之和如果大于目标,则尾指针往前推进。如果sum小于目标,则前指针往前推进。
void find2num(int *a,int n,int dest){
    int *f=a,*e=a+n-1;
    int sum=*f+*e;
    while(sum!=dest){
        if(sum<dest)sum=(*++f)+*e;
        else sum=(*--e)+*f;
    }
    if(sum==dest)cout<<*f<<" "<<*e<<endl;
}

如果数列是无序的,可以先把数列元素放进bitmap,然后查看target-array[i]是不在bitmap中,复杂度为O(n)。

第十五题:翻转二叉查找树

非递归法:利用栈
非递归遍历二叉树:

第十六题:按从上到下从左到右打印二叉树

方法:利用队列控制先进先出
void printTreeByFloor(BSTreeNode *pRoot){
    BSTreeNode *p=pRoot;
    queue<BSTreeNode*> que;
    que.push(p);
    while(!que.empty()){
        p=que.front();
        que.pop();
        cout<<p->m_nValue<<endl;
        if(p->m_pLeft!=NULL)que.push(p->m_pLeft);
        if(p->m_pRight!=NULL)que.push(p->m_pRight);
    }
}

第十七题:找出字符串中第一个只出现一次的字符

建立一个hash表记录每个字符出现的次数。然后按字符串的顺序遍历hash表,遇到=1的记录时返回。
void singleChar(const char *a){
    int hash[100];
    memset(hash,0,100*sizeof(int));
    const char *p=a;
    while(*p!='\0'){
        hash[*p++-'a']++;
    }
    p=a;
    while(*p!='\0'){
        if(hash[*p-'a']==1){
            cout<<*p<<endl;
            break;
        }
        ++p;
    }
}

第十八题:约瑟夫环。0~n形成一个圈,每次删除第m个,求剩下的数字。

直观法:用首尾相连的单链表模拟。时间复杂度O(mn),空间复杂度O(n)
数学法:没看懂。。。

第十九题:Fibonnacci数列

矩阵法:没看懂,复杂度O(logn)
动态规划复杂度O(n)
int_fast64_t fibonacci(int n){
    if(n==0)return 0;
    if(n==1)return 1;
    int_fast64_t before1=1,before2=0,now;
    for(int i=2;i<=n;++i){
        now=before1+before2;
        before2=before1;
        before1=now;
    }
    return now;
}

第二十题:数字字符串转换为整数

这个。。没啥好说的。。
int string2int(char *str){
    int sum=0;
    int z=1;
    int slen=strlen(str);
    for(int i=slen-1;i>=0;--i){
        sum+=(str[i]-'0')*z;
        z*=10;
    }
    return sum;
}
posted @ 2013-03-28 09:36  iyjhabc  阅读(273)  评论(0编辑  收藏  举报