[微软面试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; }