1、春节期间小明使用微信收到很多个红包,非常开心。在查看领取红包记录时发现,某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现,要求算法尽可能高效。给定一个红包的金额数组gifts及它的大小n,请返回所求红包的金额。
测试样例:
[1,2,3,2,2] 5
返回:2
解题思路:
采用阵地攻守的思想: 第一个数字作为第一个士兵,守阵地;count = 1; 遇到相同元素,count++; 遇到不相同元素,即为敌人,同归于尽,count--;当遇到count为0的情况,又以新的i值作为守阵地的士兵,继续下去,到最后还留在阵地上的士兵,有可能是主元素,也有可能是最后一个元素。再加一次循环,记录这个士兵的个数看是否大于数组一般即可。
int MoreThanHalfNum_Solution(int* gifts, int size) { if (gifts == NULL) { return 0;; }//参数错误 int count = 1;//计数器记录士兵的生命值 int soldier = gifts[0];//士兵初始化为第一个数字 for (int i = 1; i < size; i++) { if (soldier == gifts[i])//遇到相同的元素士兵生命值增加 { count++; } else//遇到不相同的元素士兵生命值减少 { count--; } if (count == 0)//士兵的生命值为0时将下一个元素重新赋给士兵 { soldier = gifts[++i]; count = 1;//士兵生命值为1 } } count = 0; for (int j = 0; j < size; j++) { if (soldier == gifts[j]) { count++;//计数器记录该士兵出现的次数 } } if (count > size / 2) { return soldier;//士兵出现的次数大于一半 } return 0;//没有出现一半 }
2、有36辆自动赛车和6条跑道,没有计时器的前提下,最少用几次比赛可以筛选出最快的三辆赛车?
解题思路:
1)首先将36辆车分为6组进行一次比赛,这是必不可少的,假设六组的代码分别为A,B,C,D,E,F。通过6次比赛可以分别的找到每组的第一名A1,B1,C1,D1,E1,F1。
2)接下来就可以再进行第7场比赛,让各小组的第一名A1,B1,C1,D1,E1,F1进行比赛,淘汰掉后三名假设为D1,E1,F1,进而可以将D,E,F三组整个淘汰。并且得到6组的第一名,假设为A1,同时也为36辆车的第一名。
3)进行最后一场比赛,因为第一名已经决出为A1,同时只剩下B1,C1,A2,B2,C2,A3,B3,C3,从其中找到第2名和第3名,通过分析可以得到,如果在已知的比赛结果中如果存在2辆车跑的比他快,则可以直接淘汰,因为就算成绩最好的结果下他也为第4名。
由于:
B1>B2>B3
C1>C2>C3
B1>C1>C2
所以B3,C3,C2可以直接淘汰,最后剩下的待确定的赛车为B1,C1,B2,A2,A3
综上所述,最少8次比赛则可以筛选出最快的三辆赛车。