C/C++校招笔试面试经典题目总结八

题目72:如下程序的时间复杂度为(其中m>1,e>0)()

x = m;
y = 1;
while (x - y > e)
{
x = (x + y) / 2;
    y = m / x;
}
print(x);
A:log m
B:m的平方
C:m的1/2方
D:m的1/3方

解析:
1.x=(x+y)/2=(m+1)/2 m非常大,则 x=m/2;
y=m/x, x=m/2 则 y=2;

2.x=(x+y)/2=(m/2+2)/2=m/4+1 m非常大,则 x=m/4;
y=m/x, x=m/4 则 y=4; 

3.x=(x+y)/2=(m/4+4)/2=m/8+2 m非常大,则 x=m/8;
y=m/x, x=m/8 则 y=8;

.........

x=m/2n,y=2n
当x-y=m/2 n -2 n=0时 m/2 n -2 n=0 m=22n => n=(logm)/2

题目73:求fun(484)的返回值() 

bool fun(int n){
     int sum=0;
     for(int i=1;n>sum;i=i+2)
         sum=sum+i;
     return (n==sum);
}
A: True
B:False
解析:这道题目做错了,以为是单纯的每次加2,最后加出来是个奇数。其实程勋的运行过程是这样的:
loop 1:sum=1, i=3
loop 2:sum=4, i=5
loop 3:sum=9, i=7
loop 4:sum=16,i=9
loop 5:sum=25,i=11
loop 6:sum=36,i=13
loop 7:sum=49,i=15
...
通过规律可以发现sum的值为循环次数的平方,22*22=484,循环退出时sum=484,函数返回true。

题目74:如下函数的f(1)的值为()

int f(int n){
    static int i=1;
     if(n>=5)
         return n;
     n=n+i;
     i++;
     return f(n);
}
A:5   B:6    C:7  D:8
解析:此题主要考查static,带此关键字之后变量只被初始化一次。该函数为递归调用。
f(1):n=2;i=2;调用f(2)
f(2):n=4;i=3;调用f(4)
f(4):n=7;i=4;调用f(7)
f(7):返回7
即最终函数返回结果为7

题目75:给定字符串(ASCII码0-255)数组,请在不开辟额外空间的情况下删除开始和结尾处的空格,并将中间的多个连续的空格合并成一个。例如:"   i    am a      little boy.    ",变成"i am a little boy",语言不限,但不要用伪代码作答,函数输入输出请参考如下的函数原型:

C++函数原型:
void FormatString(char str[],int len){ }
解析:
void FormatString(char str[],int len)
{
    assert(str!=NULL);  
    int i=0,j=0,k=0;
    while(str[i]==' ')i++;//i是第一个不为空的字符
    while(str[i]!='\0')
    {
        if(str[i]==' '&&str[i+1]==' '||str[i+1]=='\0')
        {
            i++;
            continue;
        }
    str[j++]=str[i++];//上边的if条件跳出之后为单词之间加了一个空字符,因为str[i]==' '&&str[i+1]!=''已跳出

    }
    str[j]='\0';
}

题目76:给定一颗二叉树,以及其中的两个node(地址均非空),要求给出这两个node的一个公共父节点,使得这个父节点与两个节点的路径之和最小。描述你程序的最坏时间复杂度,并实现具体函数,函数输入输出请参考如下的函数原型:C++函数原型:

strucy TreeNode{
     TreeNode* left;   //指向左子树
     TreeNode* right;   //指向右子树
     TreeNode* father;   //指向父亲节点
};
TreeNode* LowestCommonAncestor(TreeNode* first,TreeNode* second){ }
解析:由于这道题目中树的节点有指向父节点的指针,相对来说是比较好做的。代码如下:
int getHeight(TreeNode *node) {
    int height = 0;
    while (node) {
        height++;
        node = node->parent;
    }
    return height;
}
 
TreeNode* LowestCommonAncestor(TreeNode* first,TreeNode* second) {
    int height1 = getHeight(first), height2 = getHeight(second), diff = height1 - height2;
    if (diff < 0) {
        diff = -diff;
        while(diff--) {
             second = second->parent;
        }
    } else {
        while(diff--) {
            first = first->parent;
        }
    }
    while (first != second) {
        first = first->parent;
        second = second->parent;
    }
    return first;
}
假设树结构里边并没有指向父节点的指针,那么这个题目应该怎么做呢?剑指offer 上边有关于这种情况的讨论,下边是他山之石:首先获得到两个节点的路径,然后将其转化为寻找路径中最后的公共点,该公共点为两个节点的最低公共祖先。
bool GetNodePath(TreeNode* pRoot, TreeNode* pNode, list& path)
{
    if(pRoot == pNode)
        return true;
 
    path.push_back(pRoot);
 
    bool found = false;

    vector::iterator i = pRoot->m_vChildren.begin();
    while(!found && i < pRoot->m_vChildren.end())
    {
        found = GetNodePath(*i, pNode, path);
        ++i;
    }
 
    if(!found)
        path.pop_back();
 
    return found;
}

TreeNode* GetLastCommonNode
(
    const list& path1, 
    const list& path2
)
{
    list::const_iterator iterator1 = path1.begin();
    list::const_iterator iterator2 = path2.begin();
    
    TreeNode* pLast = NULL;
 
    while(iterator1 != path1.end() && iterator2 != path2.end())
    {
        if(*iterator1 == *iterator2)
            pLast = *iterator1;
 
        iterator1++;
        iterator2++;
    }
 
    return pLast;
}

TreeNode* GetLastCommonParent(TreeNode* pRoot, TreeNode* pNode1, TreeNode* pNode2)
{
    if(pRoot == NULL || pNode1 == NULL || pNode2 == NULL)
        return NULL;
 
    list path1;
    GetNodePath(pRoot, pNode1, path1);
 
    list path2;
    GetNodePath(pRoot, pNode2, path2);
 
    return GetLastCommonNode(path1, path2);
}

今天就到这了,未完待续哦!


你可能感兴趣的:(C++)