[心得]面试题分析与整理3

来源:互联网 发布:网络作家富豪榜 2016 编辑:程序博客网 时间:2024/05/01 15:53

按照这个写法,一个博客会写4个题目

9.走台阶问题
f(0)=0;
f(1)=1;
f(2)=1+1=2;
递推公式:
f(n)=f(n-1)+f(n-2)+f(n-3)

面试金典第221页原题。

#include <iostream>using namespace std;int count_steps(int n, int *map);int main(){    const int N=10;    int map[N];    for(int i=0;i<N;++i)    {        map[i]=-1;    }    for(int i =0; i<N;++i)    {        cout<<i<<"\t"<<count_steps(i, map)<<endl;    }    return 0;}int count_steps(int n, int *map){    if(n<0) return 0;    else if(!n) return 1;    else if(map[n]>=0)  return map[n];    else    {        map[n] = count_steps(n-1, map) + count_steps(n-2, map) + count_steps(n-3, map);        return map[n];    }}

动态规划算法对每个子问题只求解一次,将其结果保存起来,从而避免每次遇到各个子问题时重新计算答案。这里还用到了递归

10.10进制转成2进制
求所有表示方法数
例如
1 -> 1
2 -> 10, 02
3 -> 11
4 -> 100, 020, 012
5 -> 101, 021
6 -> 110,022,102
F(0)=0
F(1)=1
F(2)=2
F(3)=1=F(1)
F(4)=3=F(1)+F(2)
F(5)=2=F(2)
F(6)=F(2)+F9(3)=1+2=3

归纳出表达式:
F(0)=0
F(1)=1
F(2)=2
F(n)=F((n-1)/2) if n is odd
F(n)=F(n/2)+F((n-2)/2) if n is even

代码略
也是一个递归解法

11.递增数列中每一项都可表示为
3^i*5^j*7^k
(i,j,k>=0)
求数列第n项
1,3,5,7,9,15,21,25,27
此为面试金典第188页原题

#include <iostream>#include <queue>#include <stack>using namespace std;int getMagicNumber(int n);int getNextNum(queue<int> &q3, queue<int> &q5, queue<int> &q7, int *nextQ);int main(){    for(int i=0;i<11;++i)        cout<<i<<":\t"<<getMagicNumber(i)<<endl;    return 0;}int getMagicNumber(int n){    if(n<=0)    return 0;    queue<int> q3,q5,q7;    stack<int> s;    int cnt=0;    int nextNum, nextQ;    while(cnt<n)    {        nextNum = getNextNum(q3,q5,q7,&nextQ);        s.push(nextNum);        ++cnt;    }    return s.top();}int getNextNum(queue<int> &q3, queue<int> &q5, queue<int> &q7, int *nextQ){    int min;    if(q3.empty())    {        min=1;        *nextQ=3;    }else    {        if(q3.front()<q5.front() && q3.front()<q7.front())        {            min = q3.front();            q3.pop();            *nextQ=3;        }else if(q5.front()<q3.front() && q5.front()<q7.front())        {            min = q5.front();            q5.pop();            *nextQ=5;        }else{            min = q7.front();            q7.pop();            *nextQ=7;        }        switch(*nextQ)        {            case 3: q3.push(min*3);            case 5: q5.push(min*5);            default:q7.push(min*7);        }        return min;    }}

可以优化的地方: stack只在back函数取得末尾元素,因此可以换成queue,同时函数的接口可以简化为3个参数.

这个题目也展示了如何使用stl的queue和stack等模块

12.为二叉树找右侧邻居节点
要求递归和非递归都实现
这个问题非递归可以做一次层序遍历
在每一层都输出其右邻结点

#include <iostream>#include <queue>using namespace std;typedef struct Node* NodePointer;struct Node{    int data;    int depth;    NodePointer lChild;    NodePointer rChild;    NodePointer rBrother;};struct myQueue{};void findRBrother(NodePointer root);void addToQueue(NodePointer root, myQueue q);void findRBrotherRecursive(NodePointer root);int main(){    NodePointer root=0;    findRBrother(root);    findRBrotherRecursive(root);    return 0;}void findRBrother(NodePointer root){    if(!root)   return;    root->depth = 0;    queue<NodePointer> q;    NodePointer last=0, next;    while(!q.empty())    {        next = q.front();        q.pop();        q.push(next->lChild);        q.push(next->rChild);        if(last->depth == next->depth)        {            last->rBrother = next;        }        last = next;    }}void findRBrotherRecursive(NodePointer root){    int front=0,rear=0;    NodePointer left,right;    left = root;    right = root->lChild;    queue<NodePointer> q;    if(!root)   return;    if(root->lChild)        q.push(root->lChild);    if(root->rChild)        q.push(root->rChild);    while(right)    {        left->rBrother = right;        left = right;        right=right->lChild;        if(left->lChild)            q.push(left->lChild);        if(left->rChild)            q.push(left->rChild);    }    if(q.empty())   return;    left = q.front();    q.pop();    findRBrotherRecursive(left);}

这个代码体现了数据结构的扩展能力。

这里再附上层序遍历的代码加深一下印象:

void levelOrder(NodePointer root){    int front=0, rear = 0;    queue<NodePointer> q;    if(!root)   return;    q.push(root);    while(1)    {        root = q.front();        q.pop();        if(!root)   break;        cout<<root->data<<endl;        if(root->lChild)            q.push(root->lChild);        if(root->rChild)            q.push(root->rChild);    }}
0 0
原创粉丝点击