来自:http://blog.csdn.net/v_july_v/article/details/6890054
题目1:Tango是微软亚洲研究院的一个试验项目,如图1所示。研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的ID也在表中,你能快速找出这个传说中的Tango水王吗?
题目简化为:求数组中出现一半以上次数的数?
思想1:排序后,输出a[n/2];
sort(a,a+N); return a[N/2];
#include<iostream> #include<algorithm> using namespace std; int FindCandidate(int *arr,int n);//通过次数来找出水王 int FindCandidate2(int *arr,int n);//通过排序 int main() { int n=-1; cin>>n; int *arr=new int[n]; for(int i=0;i<n;i++) cin>>arr[i]; cout<<FindCandidate2(arr,n)<<endl; delete[] arr; return 0; } int FindCandidate(int *arr,int n) { int nTimes=0,candidate=-1; for(int i=0;i<n;i++) { if(nTimes==0) { candidate=arr[i]; nTimes=1; }else { if(arr[i]==candidate) ++nTimes; else --nTimes; } } return candidate; } int FindCandidate2(int *arr,int n) { sort(arr,arr+n); return arr[n/2]; }
题目2:输入一个字符串,打印出该字符串中字符的所有排列
思想:采用递归方式。比如说abc这个字符串,可以分为a+bc的全排列,b+ac的全排列,c+ab的全排列。
#include<iostream> #include<algorithm> using namespace std; void permulation(char *str,int start,int len); int k=1; int main() { char str[256]={0}; cin>>str; permulation(str,0,strlen(str)); return 0; } void permulation(char *str,int start,int len) { if(len<=1) { cout<<k++<<" "<<str<<endl; return; } for(int i=start;i<start+len;i++) { swap(str[i],str[start]);// permulation(str,start+1,len-1); swap(str[i],str[start]); } }
题目3:一个台阶总共有n 级,如果一次可以跳1 级,也可以跳2 级。求总共有多少总跳法,并分析算法的时间复杂度。
分析:
台阶数 | 总方法数 | 具体 |
1 | 1 | 1、1 |
2 | 2 | 1、1+1 2、2 |
3 | 3 | 1、1+1+1 2、1+2 3、2+1 |
为什么得出这样的式子,当面对n级台阶,第一次可以跳1级,则剩下n-1级,即f(n-1);第一次跳2级,则剩下n-2级,即f(n-2)。所以f(n)=f(n-1)+f(n-2)
其实,这就是斐波那契数列。
实现:
1.递归实现:
int fibona(int n) { if(n<=0) return -1; else if(n==1) return 1; else if(n==2) return 2; else return fibona(n-1)+fibona(n-2); }缺点:当台阶数比较大时,递归层次比较深。而且存在重复计算。
2、递归方式不变,以空间换时间。在递归过程中,如果求出的某一个数的结果,不在数组中,则存入到数组中。
3、不用递归,该用迭代方式。即从f(3)->f(4)->f(5).....->f(n)
int fibona2(int n) { int result1=1,result2=2,result=0; if(n<=0) return -1; else if(n==1) return result1; else if(n==2) return result2; for(int i=3;i<=n;i++) { result=result1+result2; if(i%2!=0) result1=result;//奇数,则将结果赋值给result1 else result2=result;//偶数,则将结果赋值给result2 } return result; }
题目4:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)
分析:这到底比之前的不改变正负数之间相对顺序重新排列数组.时间O(N),空间O(1)简单,因为没要求保证相对顺序,而且只要求时间复杂度为O(n)。
申请两指针,一个指针p指向数组头,一个指针q指向数组尾。
#include<iostream> #include<algorithm> using namespace std; int exchange(int *a,int n); int main() { int n; cout<<"请输入数组长度"<<endl; cin>>n; if(n<=0) cout<<"n应该大于0"<<endl; else { int *a=new int[n]; for(int i=0;i<n;i++) cin>>a[i]; exchange(a,n); cout<<"交换过后的数组为:"<<endl; for(int i=0;i<n;i++) cout<<a[i]<<" "; cout<<endl; delete[] a; } return 0; } int exchange(int *a,int n) { int *p=a,*q=a+n-1; while(p<q) { while(*p%2!=0)//找到偶数 ++p; while(*q%2==0)//找到奇数 --q; if(p<q) { swap(*p,*q); ++p; --q; }else break; } return 0; }
题目5:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b
思想:第一次遍历字符串,将字符出现次数,存入到hash数组中.hash数组key位字符的Ascii码,value为字符出现次数.
第二次遍历字符串,找出第一个只出现一次的字符.
#include<iostream> using namespace std; char findOnlyOne(char *str); int main() { char str[256]={0}; cin>>str; cout<<"第一次只出现一次的字符为:"<<findOnlyOne(str)<<endl; return 0; } char findOnlyOne(char *str) { int num[256]; memset(num,0,sizeof(num)); char *p=str; while(*p!='\0') { num[*p]++; ++p; } p=str; while(*p!='\0') { if(num[*p]==1) break; ++p; } return *p; }