每日一题----no.914卡牌分组
- 把一堆卡牌分组,每组n张,要求n不少于2,组内数字相同。
- 注意相同的可能被分成多个组。
- 因此是选最大公约数,求出以后进行计算。(理由:比如六个1,四个2,这时候为了保证每个组的数量是一样的,就拆分,公约数就是新的拆分组内成员数)
- 使用map来完成,注意map下标是deck[i],不是i
- 遇到vector长度0或者1直接返回,其余的长度一定够,要么多余两组,要么一组大于等于2的,后面不用在判断长度的问题
class Solution { public: int gcd(int a,int b) { if(a<b) { int temp=a; a=b; b=temp; } if(b==0) return a; return gcd(b,a%b); } bool hasGroupsSizeX(vector<int>& deck) { int len=deck.size(); if(len==0||len==1) return false; map<int,int>mp; int count=0; for(int i=0;i<=len-1;i++) { if(mp.find(deck[i])==mp.end()) { mp[deck[i]]=1; } else mp[deck[i]]++; } map<int,int>::iterator it=mp.begin(); int temp=it->second; for(it;it!=mp.end();it++) { int temp=gcd(temp,it->second); if(temp<2) return false; //printf("%d %d ",it->first,it->second); } return true; } };
注意这道题数据范围并不大可以直接用数组下标来完成。
class Solution { public: int gcd(int a,int b) { if(a<b) { int temp=a; a=b; b=temp; } if(b==0) return a; return gcd(b,a%b); } bool hasGroupsSizeX(vector<int>& deck) { if(deck.size()<2) return false; int a[10005]={0}; for(int i=0;i<deck.size();i++) a[deck[i]]++; int temp; for(int i=0;i<=10000;i++) { if(a[i]) { //printf("%d %d ",i,a[i]); if(temp==0) temp=a[i]; else { temp=gcd(temp,a[i]); if(temp<2) return false; } } } return true; } };
每日一题补题--面试题62
- 约瑟夫环问题,一组有n个人,每次取出第m个(下标m-1),到只剩下最后一个人的时候停止
- 问最后一个人原始的下标是多少
- f(n,m)=(f(n-1,m)+m)%n
- 已知最后一轮f(1,m)=0,回推可以求出结果,每次向后推m个就是回到上一轮的状态,但是上一轮有可能没有这么多,那么这个数字其实是从前一轮过来的,所以是mod n哦
- 递归和迭代都在代码里面,看清楚。
class Solution { public: int lastRemaining(int n, int m) { /*if(n==1) return 0; return (lastRemaining(n-1,m)+m)%n;*/ int ans=0; for(int i=2;i<=n;i++) { ans=(ans+m)%i; } return ans; } };