声明:所有试题均来自网络。解答仅作参考,如对解答有疑问,或者有更好的解法,欢迎留言交流。
11、求1+2+…+n。
要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。
//利用构造函数求解
class Temp
{
public:
Temp()
{
++N;
Sum+=N;
}
static void Reset()
{
N=0;
Sum=0;
}
static int GetSum()
{
return Sum;
}
private:
static int N;
static int Sum;
};
int Temp::N=0;
int Temp::Sum=0;
int CountSum(int n)
{
if(n<1)
return 0;
Temp::Reset();
Temp* temp = new Temp[n];
delete[] temp;
temp = NULL;
return Temp::GetSum();
}
12、链表中倒数第k个结点
输入一个链表,输出该链表的倒数第k个结点。设尾结点为倒数第1个结点,例如一个链表
从头到尾结点的值依次为1、2、3、4、5、6,则倒数第三个结点为4。
listNode* FindKthToTail(listNode* head,int k)
{
if(head==NULL || k<1)
return NULL;
listNode* ret = head;
for (int i=1;i!=k;++i)
{
if(head->next!=NULL)
head = head->next;
else
return NULL;
}
while(head->next!=NULL)
{
head = head->next;
ret = ret->next;
}
return ret;
}
13、和为s的两个数字
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。
如果有多对数字的和等于s,输出任意一对即可。
bool FindNumberWithSum(int* data,int length,int sum,int& num1,int& num2)
{
if(data==NULL || length<1)
return false;
bool ret =false;
int* begin = data;
int* end = data+length-1;
while(begin!=end)
{
if (*begin+*end<sum)
++begin;
else if(*begin+*end>sum)
--begin;
else
{
num1 = *begin;
num2 = *end;
ret = true;
break;
}
}
return ret;
}
14、二元查找树的镜像
输入一颗二元查找树,将该树转换为它的镜像,
用递归和循环两种方法完成树的镜像转换。
void MirrorTransform(BinaryTreeNode* root)
{
if(root==NULL)
return;
if(root->left!=NULL || root->right!=NULL)
{
BinaryTreeNode* temp = root->left;
root->left = root->right;
root->right = temp;
}
if(root->left!=NULL)
MirrorTransform(root->left);
if(root->right!=NULL)
MirrorTransform(root->right);
}
void MirrorIteratively(BinaryTreeNode* root)
{
if(root==NULL)
return;
queue<BinaryTreeNode*> queueOfNode;
queueOfNode.push(root);
while (!queueOfNode.empty())
{
BinaryTreeNode* node = queueOfNode.front();
BinaryTreeNode* temp = node->left;
node->left = node->right;
node->right = temp;
queueOfNode.pop();
if(node->left!=NULL)
queueOfNode.push(node->left);
if(node->right!=NULL)
queueOfNode.push(node->right);
}
}
15、从上往下打印二叉树
输入一颗二叉树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印。
例如输入
8
/ \
6 10
/ \ / \
5 7 9 11
输出8 6 10 5 7 9 11。
void PrintFromUpToBottom(BinaryTreeNode* root)
{
if(root==NULL)
return;
queue<BinaryTreeNode*> queueOfNode;
queueOfNode.push(root);
while (!queueOfNode.empty())
{
BinaryTreeNode* node = queueOfNode.front();
queueOfNode.pop();
cout<<node->value<<" ";
if(node->left!=NULL)
queueOfNode.push(node->left);
if(node->right!=NULL)
queueOfNode.push(node->right);
}
}
16、第一个只出现一次的字符
题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。
分析:这道题是2006年google的一道笔试题。
char FindFirstChar(char* data)
{
assert(data!=NULL && *data != '\0');
int temp[256]={0};
char* ret;
for (char* c =data;*c != '\0';++c)
++temp[*c];
for (ret = data;*ret != '\0';++ret)
{
if(temp[*ret]==1)
break;
}
return *ret;
}
17、约瑟夫环
题目:n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。
当一个数字删除后,从被删除数字的下一个继续删除第m个数字。
求出在这个圆圈中剩下的最后一个数字。
int LastRemaining(int n,int m)
{
if(n<1 || m<1)
return -1;
list<int> listOfNum;
for(int i=0;i!=n;++i)
listOfNum.push_back(i);
list<int>::iterator current = listOfNum.begin();
while (listOfNum.size()>1)
{
for (int i = 1;i!=m;++i)
{
++current;
if(current==listOfNum.end())
current=listOfNum.begin();
}
list<int>::iterator helper = ++current;
if(helper==listOfNum.end())
helper=listOfNum.begin();
--current;
listOfNum.erase(current);
current = helper;
}
return listOfNum.front();
}
18、斐波那契数列
题目:定义Fibonacci数列如下:
{ 0 n=0
f(n)= { 1 n=1
{ f(n-1)+f(n-2) n>1
输入n,用最快的方法求该数列的第n项。
分析: 由于递归的写法效率太过低下,要求用非递归实现。
int Fibonacci(int n)
{
if(n<0)
return -1;
if(n==0 || n==1)
return n;
int helper1 = 0;
int helper2 = 1;
for (int i=2;i!=n;++i)
{
int temp = helper2;
helper2 += helper1;
helper1 = temp;
}
return helper1+helper2;
}
19、转换字符串为整数
题目:输入一个表示整数的字符串,把该字符串转换成整数并输出。
例如输入字符串"345",则输出整数345。
bool g_InvalidInputs = false;
int StrToInt(const char* str)
{
if(str==NULL || *str=='\0')
{
g_InvalidInputs = true;
return 0;
}
bool minus = false;
if(*str=='+')
++str;
else if(*str=='-')
{
minus = true;
++str;
}
long long ret = 0;
for (char* c = str;*c!='\0';++c)
{
if(*c<='9' && *c>='0')
{
ret = ret*10 + *c-'0';
if((!minus && ret>0x7FFFFFFF) || (minus && -ret<(signed int)0x80000000))
{
g_InvalidInputs = true;
return 0;
}
}
else
{
g_InvalidInputs = true;
return 0;
}
}
if(minus)
ret = - ret ;
g_InvalidInputs = false;
return ret;
}
20、数列求和输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,
使其和等于 m ,要求将其中所有的可能组合列出来。
int g_N = 0; //全局变量,存储n的值
void FindSum(int n,int m)
{
int* data = new int[n+1];
for (int i=0;i!=n+1;++i)
*(data+i)=0;
g_N = n;
FindSum(n,m,data);
delete[] data;
g_N = 0;
}
void FindSum(int n,int m,int* data)
{
if(n<1 || m<1)
return;
if(m<n)
n=m;
if(n==m)
{
*(data+n)=1;
PrintData(data);
}
*(data+n)=1;
FindSum(n-1,m-n,data);
*(data+n)=0;
FindSum(n-1,m,data);
}
void PrintData(int* data)
{
for (int i=1;i<=g_N;++i)
{
if(*(data+i)==1)
cout<<i<<" ";
}
cout<<endl;
}
欢迎大家访问我的独立技术博客 道合|SameIdeal.com