您的位置:首页 > 其它

在线笔试题汇总 4.12

2016-04-12 21:18 239 查看
1)问:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

答:

分析一下代码: 这段小小的代码,很是巧妙。

如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。

举个例子:一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。

class Solution {
public:
int  NumberOf1(int n) {
int count = 0;
while(n!= 0){
count++;
n = n & (n - 1);
}
return count;
}
};

2)问:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。

答:

class Solution {
public:
int Fibonacci(int n) {
int* array=new int
;
array[0]=1;
array[1]=1;
array[2]=2;
for(int i=3;i<n;i++)
array[i]=array[i-1]+array[i-2];
return array[n-1];
};
};


3)问:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

答:

对于第n个台阶来说,只能从n-1或者n-2的台阶跳上来,所以

F(n) = F(n-1) + F(n-2)

斐波拉契数序列,初始条件

n=1:只能一种方法

n=2:两种

递归一下就好了

class Solution {
public:
int jumpFloor(int number) {
if(number <= 0)
return 0;
else if(number == 1)
return 1;
else if(number == 2)
return 2;
else
return jumpFloor(number-1) + jumpFloor(number-2);
}
};


4)问:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

答:

依旧是斐波那契数列

2*n的大矩形,和n个2*1的小矩形

其中target*2为大矩阵的大小

有以下几种情形:

1⃣️target <= 0 大矩形为<= 2*0,直接return 1;

2⃣️target = 1大矩形为2*1,只有一种摆放方法,return1;

3⃣️target = 2 大矩形为2*2,有两种摆放方法,return2;

4⃣️target = n 分为两步考虑:

第一次摆放一块 2*1 的小矩阵,则摆放方法总共为f(target - 1)

第一次摆放一块1*2的小矩阵,则摆放方法总共为f(target-2)

因为,摆放了一块1*2的小矩阵(用√√表示),对应下方的1*2(用××表示)摆放方法就确定了,所以为f(targte-2)

代码:

public:class Solution {
int rectCover(int number) {
if(number<=0)return 1;
else if(number==1)return 1;
else if(number==2)return 2;
else return rectCover(number-1)+rectCover(number-2);
}
};


6)问:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

答:

关于本题,前提n个台阶会有一次n阶的跳法。分析如下:

f(1) = 1

f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。

f(3) = f(3-1) + f(3-2) + f(3-3)

...

f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n)

说明:

1. 这里的f(n) 代表的是n个台阶有一次1,2,...n阶的 跳法数。

2. n = 1时,只有1种跳法,f(1) = 1

3. n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)

4. n = 3时,会有三种跳得方式,1阶、2阶、3阶,

那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)

因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)

5. n = n时,会有n中跳的方式,1阶、2阶...n阶,得出结论:

f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)

6. 由以上已经是一种结论,但是为了简单,我们可以继续简化:

f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)

f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)

可以得出:

f(n) = 2*f(n-1)

7. 得出最终结论,在n阶台阶,一次有1、2、...n阶的跳的方式时,总得跳法为:

| 1 ,(n=0 )

f(n) = | 1 ,(n=1 )

| 2*f(n-1),(n>=2)

以后遇到这类问题,用类比法列公式就好了。

class Solution {
public:
int jumpFloorII(int number) {
if(number<=0) return -1;
else if(number==1) return 1;
else return 2*jumpFloorII(number-1);
}
};


7)问:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

答:

栈:限定仅在表尾进行插入和删除操作的线性表,栈顶(top)栈底(bottom)

队列:只允许在一端进行插入操作,而在另一端进行删除操作的线性表

入队:将元素进栈A

出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈;

如果不为空,栈B直接出栈。

class Solution
{
public:
void push(int node) {
stack1.push(node);
}

int pop() {
int a;
if(stack2.empty())
{
while(!stack1.empty())
{
a=stack1.top();
stack2.push(a);
stack1.pop();
}
}
a=stack2.top();
stack2.pop();
return a;
}

private:
stack<int> stack1;
stack<int> stack2;
};


8)问:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

答:先序遍历第一个位置肯定是根节点node,中序遍历的根节点位置在中间p,在p左边的肯定是node的左子树的中序数组,p右边的肯定是node的右子树的中序数组。另一方面,先序遍历的第二个位置到p,也是node左子树的先序子数组,剩下p右边的就是node的右子树的先序子数组。把四个数组找出来,分左右递归调用即可

/**
* Definition for binary tree
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) {
int in_size = in.size();
if(in_size == 0)
return NULL;
vector<int> pre_left, pre_right, in_left, in_right;
int val = pre[0];
TreeNode* node = new TreeNode(val);//root node is the first element in pre
int p = 0;
for(p; p < in.size(); ++p){
if(in[p] == val) //Find the root position in in
break;
}
for(int i = 0; i < in.size(); ++i){
if(i < p){
in_left.push_back(in[i]);//Construct the left pre and in
pre_left.push_back(pre[i+1]);
}
else if(i > p){
in_right.push_back(in[i]);//Construct the right pre and in
pre_right.push_back(pre[i]);
}
}
node->left = reConstructBinaryTree(pre_left, in_left);
node->right = reConstructBinaryTree(pre_right, in_right);
return node;
}
};


9)有一棵二叉树,请设计一个算法,按照层次打印这棵二叉树。

给定二叉树的根结点root,请返回打印结果,结果按照每一层一个数组进行储存,所有数组的顺序按照层数从上往下,且每一层的数组内元素按照从左往右排列。保证结点数小于等于500。

class TreePrinter {
public:
vector<vector<int> > printTree(TreeNode* root) {
TreeNode* last=root;
TreeNode* nlast=NULL;
vector<vector<int>> res;
vector<int> cur_line;
queue<TreeNode*> que;
que.push(last);
while(!que.empty())
{
TreeNode* front=que.front();
que.pop();
cur_line.push_back(front->val);
if(front->left)
{
que.push(front->left);
nlast=front->left;
}
if(front->right)
{
que.push(front->right);
nlast=front->right;
}
if(front==last)
{
res.push_back(cur_line);
cur_line.clear();
last=nlast;
}
}
return res;
}
};


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: