C++面试题
来源:互联网 发布:比特币源码编译 编辑:程序博客网 时间:2024/06/02 05:50
1. 一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。求总共有多少总跳法?
[cpp] view plain copy
- /***********************************************************************
- 题目:一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。
- 求总共有多少总跳法。
- 分析:首先我们考虑最简单的情况。如果只有1级台阶,那显然只有一种跳法。
- 如果有2级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1级;
- 另外一种就是一次跳2级。
- 现在我们再来讨论一般情况。我们把n级台阶时的跳法看成是n的函数,记为f(n)。
- 当 n=1 时有 1 种跳法;当 n=2 时有 2 种跳法;
- 当n>2时,第一次跳的时候就有两种不同的选择:
- 一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,
- 即为f(n-1);另外一种选择是第一次跳2级,此时跳法数目等于后面剩下的n-2级
- 台阶的跳法数目,即为f(n-2)。
- 因此n级台阶时的不同跳法的总数f(n)=f(n-1)+ f(n-2)。
- ***********************************************************************/
- #include <iostream>
- using namespace std;
- int f(int n)
- {
- if(n < 1)
- {
- cout<<"台阶数至少为1!"<<endl;
- return -1;
- }
- if(1 == n)
- return 1;
- if(2 == n)
- return 2;
- return f(n-1) + f(n-2);
- }
- int main()
- {
- int num;
- cout<<"请输入台阶数: ";
- cin>>num;
- cout<<"共有 "<<f(num)<<" 种跳法."<<endl;
- return 0;
- }
2. 求子数组的最大和
[cpp] view plain copy
- /************************************************************************
- 题目: 输入一个整形数组,数组里有正数也有负数。
- 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
- 求所有子数组的和的最大值。要求时间复杂度为O(n)。
- 例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5, 和最大的子数组为3, 10, -4, 7, 2,
- 因此输出为该子数组的和18。
- ************************************************************************/
- #include <iostream>
- using namespace std;
- int getMaxSubArraySum(int R[],int n);
- int main()
- {
- int arr[8] = {1,-2,3,10,-4,7,2,-5};
- int maxSubSum = getMaxSubArraySum(arr,8);
- cout<<maxSubSum<<endl;
- return 0;
- }
- int getMaxSubArraySum(int R[],int n)
- {
- int maxSumValue = 0;//结果
- int subArraySumValue = 0;//累加和
- int max = R[0];//保存数组中的最大值
- for(int i=0;i<n;++i)
- {
- subArraySumValue += R[i];
- if(subArraySumValue < 0)
- {
- subArraySumValue = 0;
- }
- if(subArraySumValue > maxSumValue)
- {
- maxSumValue = subArraySumValue;
- }
- if(max < R[i])
- {
- max = R[i];
- }
- }
- if(max < 0)
- {
- //若数组中所有的数都为负数,则返回最大的一个数
- return max;
- }
- return maxSumValue;
- }
3. 将二元查找树变成排序的双向链表
[cpp] view plain copy
- /**********************************************************
- 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
- 要求: 不能创建任何新的结点,只能调整指针的指向。
- **********************************************************/
[cpp] view plain copy
- /**********************************************************
- 思路: 1.构造二叉查找树; 2.中序遍历二叉查找树;
- 3.将访问到的结点调整为双向链表。
- **********************************************************/
- //测试程序
- #include <iostream>
- using namespace std;
- //定义二元查找树结点的数据结构
- struct BSTreeNode
- {
- int m_value;
- BSTreeNode *m_pLeft;
- BSTreeNode *m_pRight;
- };
- BSTreeNode *pHead = NULL;
- BSTreeNode *pIndex = NULL;//指向前一个结点
- //建立二叉排序树
- void addBSTreeNode(BSTreeNode *&pCurrent, int val);
- //中序遍历,同时调整结点指针
- void inOrderBSTreeNode(BSTreeNode *pNode);
- //调整结点指针
- void convert2DoubleLinkedList(BSTreeNode *pCurrent);
- int main()
- {
- BSTreeNode *pRoot = NULL;
- addBSTreeNode(pRoot,10);
- addBSTreeNode(pRoot,6);
- addBSTreeNode(pRoot,14);
- addBSTreeNode(pRoot,4);
- addBSTreeNode(pRoot,8);
- addBSTreeNode(pRoot,12);
- addBSTreeNode(pRoot,16);
- inOrderBSTreeNode(pRoot);
- return 0;
- }
- void addBSTreeNode(BSTreeNode *&pCurrent, int val)
- {
- if(NULL == pCurrent)
- {
- BSTreeNode *pNode = new BSTreeNode();
- pNode->m_value = val;
- pNode->m_pLeft = NULL;
- pNode->m_pRight = NULL;
- pCurrent = pNode;
- }
- else
- {
- if(pCurrent->m_value < val)
- {
- addBSTreeNode(pCurrent->m_pRight,val);
- }
- else if(pCurrent->m_value > val)
- {
- addBSTreeNode(pCurrent->m_pLeft,val);
- }
- else
- {
- cout<<"Node repeated!!!"<<endl;
- }
- }
- }
- void inOrderBSTreeNode(BSTreeNode *pNode)
- {
- if(NULL == pNode)
- {
- return;
- }
- if(NULL != pNode->m_pLeft)
- {
- inOrderBSTreeNode(pNode->m_pLeft);
- }
- convert2DoubleLinkedList(pNode);
- if(NULL != pNode->m_pRight)
- {
- inOrderBSTreeNode(pNode->m_pRight);
- }
- }
- void convert2DoubleLinkedList(BSTreeNode *pCurrent)
- {
- //使当前结点的左指针指向双向链表中的最后一个结点
- pCurrent->m_pLeft = pIndex;
- if(NULL == pIndex)//双向链表尚未建立
- {
- pHead = pCurrent;
- }
- else
- {
- pIndex->m_pRight = pCurrent;
- }
- pIndex = pCurrent;
- cout<<pCurrent->m_value<<" ";
- }
4. 找出数组中唯一出现2次的数
[cpp] view plain copy
- /***********************************************************************
- 题目: 假设你有一个用1001个整数组成的数组,这些整数是任意排列的,
- 但是你知道所有的整数都在1到1000(包括1000)之间。
- 此外,除一个数字出现两次外,其他所有数字只出现一次。
- 假设你只能对这个数组做一次处理,用一种算法找出重复的那个数字。
- 如果你在运算中使用了辅助的存储方式,那么你能找到不用这种方式的算法吗?
- ***********************************************************************/
- /***********************************************************************
- 思路: (1001个数异或结果)与(1-1000异或的结果)再做异或,即可。
- 原理: 设重复数为A, 其余999个数异或结果为B。
- 1001个数异或结果为A^A^B, 1-1000异或结果为A^B。
- 由于异或满足交换律和结合律, 且X^X = 0, 0^X = X;
- 则有(A^B)^(A^A^B)=A^B^B=A
- ***********************************************************************/
- //测试程序
- #include <iostream>
- using namespace std;
- void showRepeated(int R[],int n);
- int main()
- {
- int a[] = {5,2,4,3,4,1,6};
- showRepeated(a,6);
- return 0;
- }
- void showRepeated(int R[],int n)
- {
- int result = 0;
- for(int i=0;i<=n;++i)
- {
- result ^= R[i];
- }
- for(int i=1;i<=n;++i)
- {
- result ^= i;
- }
- cout<<"result = "<<result<<endl;
- }
5. 输入一个数,判断它是不是回文数
[cpp] view plain copy
- //输入一个数,判断它是不是回文数。
- #include <iostream>
- using namespace std;
- bool isPalindromicNumber(int x);
- int main()
- {
- int x = 0;
- cout<<"Please input a number:";
- cin>>x;
- if(isPalindromicNumber(x))
- cout<<x<<"是回文数."<<endl;
- else
- cout<<x<<"不是回文数."<<endl;
- return 0;
- }
- bool isPalindromicNumber(int x)
- {
- int y = 0;
- int result = 0;
- int temp = x;
- while(x!=0){
- y = x%10;
- x /= 10;
- result = result*10+y;
- }
- if(result==temp)
- return true;
- else
- return false;
- }
6. 编写一个程序,计算一个字符串中子串出现的次数
[cpp] view plain copy
- #include <stdio.h>
- #include <string.h>
- int getCount(char* str,char* substr)
- {
- int i=0,j=0,count=0;
- while(*(str+i)){
- if(*(str+i)==*(substr+j)){
- i++;
- j++;
- }
- else{
- if(j==0)
- i++;
- else
- j = 0;
- }
- if(j==strlen(substr)){
- count++;
- j = 0;
- }
- }
- return count;
- }
- int main()
- {
- char* str = "HHiHelloHHioHhiHrlHIodHioplloHHii";
- char* substr = "Hi";
- int count = getCount(str,substr);
- printf("子串出现的次数:%d\n",count);
- return 0;
- }
7. 求1~1000之间的完全数
[cpp] view plain copy
- //如果一个数恰好等于它的真因子之和,则称该数为“完全数”。
- //根据完全数的定义,先计算所选取的整数num的真因子,将各因子累加于sum,若sum等于num,则num为完全数。
- #include <iostream>
- using namespace std;
- bool isWanQuanShu(int num);//判断num是否为完全数
- int main(){
- for(int i=2;i<1000;i++){
- if(isWanQuanShu(i)){
- cout<<i<<" ";
- }
- }
- cout<<endl;
- return 0;
- }
- bool isWanQuanShu(int num){
- int sum = 0;
- for(int i=1;i<=num/2;i++)
- if(num%i == 0)
- sum += i;
- if(sum == num)
- return true;
- else
- return false;
- }
8. 求1+2+…+n
[cpp] view plain copy
- /**********************************************************
- 题目: 求1+2+…+n
- 要求: 不能使用乘除法、for、while、if、else、switch、case
- 等关键字以及条件判断语句(A?B:C)
- **********************************************************/
- /**********************************************************
- 思路: 定义一个类,我们new一个含有n个这种类型元素的数组,那么该类
- 的构造函数将会被调用n次。可以将需要执行的代码放到构造函数里。
- **********************************************************/
- #include <iostream>
- using namespace std;
- class Temp
- {
- public:
- Temp()
- {
- ++m_n;
- m_sum += m_n;
- }
- static void Reset(){m_n = 0; m_sum = 0;}
- static int getSum(){return m_sum;}
- private:
- static int m_n;
- static int m_sum;
- };
- int Temp::m_n = 0;
- int Temp::m_sum = 0;
- int Sum(int n)
- {
- Temp::Reset();
- Temp *tmp = new Temp[n];
- delete[] tmp;
- tmp = NULL;
- return Temp::getSum();
- }
- int main()
- {
- cout<<Sum(100)<<endl;
- return 0;
- }
9. 输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。
[cpp] view plain copy
- /**************************************************************
- 题目:输入一个已经按升序排序过的数组和一个数字, 在数组中查找两个数,
- 使得它们的和正好是输入的那个数字。 要求时间复杂度是O(n)。如果有多对
- 数字的和等于输入的数字,输出任意一对即可。
- 例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。
- **************************************************************/
- #include <iostream>
- using namespace std;
- void find(int R[],int n,int sum);
- int main()
- {
- int arr[6] = {1,2,4,7,11,15};
- int sum = 15;
- find(arr,6,sum);
- return 0;
- }
- void find(int R[],int n,int sum)
- {
- int i=0;
- int j=n-1;
- while(i < j)
- {
- if(R[i]+R[j] == sum)
- {
- cout<<sum<<" = "<<R[i]<<" + "<<R[j]<<endl;
- return;
- }
- R[i]+R[j]<sum ? ++i : --j;
- }
- cout<<"Cannot find!"<<endl;
- }
10. 约瑟夫环
[cpp] view plain copy
- /****************************************************************************
- 题目:n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字
- (第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除
- 数字的下一个继续删除第m个数字。求出在这个圆圈中剩下的最后一个数字。
- 分析:既然题目有一个数字圆圈,很自然的想法是我们用一个数据结构来模拟这个圆圈。
- 在常用的数据结构中,我们很容易想到用环形列表。我们可以创建一个总共有m个数字的环形列表,
- 然后每次从这个列表中删除第m个元素。 我们用STL中std::list来模拟这个环形列表。
- 由于list并不是一个环形的结构,因此每次跌代器扫描到列表末尾的时候,
- 要记得把跌代器移到列表的头部。这样就是按照一个圆圈的顺序来遍历这个列表了。
- 这种思路需要一个有n个结点的环形列表来模拟这个删除的过程,因此内存开销为O(n)。
- 而且这种方法每删除一个数字需要m步运算,总共有n个数字,因此总的时间复杂度是O(mn)。
- ****************************************************************************/
- #include <iostream>
- using namespace std;
- #include <list>
- int getLastNumber(list<int> numList,unsigned m);
- int main()
- {
- list<int> numList;
- unsigned n;
- unsigned m;
- cout<<"请输入n:";
- cin>>n;
- cout<<"请输入m:";
- cin>>m;
- if(n<1 || m<1)
- {
- cout<<"\n输入有误!\n"<<endl;
- return -1;
- }
- for(unsigned i=0;i<n;++i)
- numList.push_back(i);
- cout<<"Last Number: "<<getLastNumber(numList,m)<<endl;
- return 0;
- }
- int getLastNumber(list<int> numList, unsigned m)
- {
- list<int>::iterator currentIter = numList.begin();
- list<int>::iterator nextIter;
- while(numList.size() > 1)
- {
- for(unsigned i=1;i<m;++i)
- {
- ++currentIter;
- if(currentIter == numList.end())
- currentIter = numList.begin();
- }
- // 找到第m个数,将其从list中移出
- nextIter = ++currentIter;
- if(nextIter == numList.end())
- nextIter = numList.begin();
- --currentIter;
- numList.erase(currentIter);
- currentIter = nextIter;
- }
- return *(currentIter);
- }
阅读全文
0 0
- C语言面试题
- c/c++面试题
- c/c++面试题
- C/C++面试题
- c/c++面试题
- c面试题
- C语言面试题
- c/c++面试题
- C语言面试题
- C语言面试题
- C/C++ 面试题
- C面试题
- C#.NET面试题
- C/C++面试题
- c/c++面试题
- c语言面试题
- C#.NET面试题
- c语言面试题
- 进程和线程的数据结构
- 管道容量以及管道底层缓冲区如何组织
- 001redis简介
- jQuery LigerUI 插件中ligerTree的使用介绍
- 统计字符串中某一字符出现的次数(不分大小写,字符不含空格)
- C++面试题
- 单例模式的双重检测问题
- Linux 学习(五)--- CentOS 6.6 网络配置
- Maven仓库—Nexus环境搭建及使用
- POJ 1226 Substrings 笔记
- LD_LIBRARY_PATH环境变量的设置
- 导出Excel中文名
- 逐浪字库新字库出炉!
- 剑指Offer——(23)二叉搜索树的后序遍历序列