名企招聘经典面试编程题集锦[第11-20题]

声明:所有试题均来自网络。解答仅作参考,如对解答有疑问,或者有更好的解法,欢迎留言交流。

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

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值