来自: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];
思想2:出现一半以上次数的数减去其他数的总次数,结果大于0
#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指向数组尾。
- p右移,找到一个偶数
- q左移,找一个奇数
- p与q所指向的数互换,并且p右移一位,q左移一位
- 循环直到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;
}
这篇博客探讨了微软亚洲研究院的Tango项目,挑战寻找‘水王’,即发帖超过一半的用户。文章通过简化问题,提出解决数组中出现次数过半的元素的算法,并进一步讨论字符串排列、台阶跳法的斐波那契数列解决方案,以及如何在O(n)时间内调整数组奇偶顺序的问题。最后,介绍了一个寻找字符串中第一个只出现一次字符的方法。

被折叠的 条评论
为什么被折叠?



