概述:
现在有n个魔法师(2<=n<=100000),这n个魔法师都有自己的魔法值ai(1<=ai<=1000000000),他们为了证明自己是最强的魔法师便开始了争夺战,任意一个魔法师都可以对其他的魔法师发起攻击,每次攻击,被攻击的魔法师损失掉的魔法值是攻击者当前的魔法值,当魔法值小于等于0的时候淘汰出局,问最后只剩下一名魔法师时,他的魔法值最少是多少。
输入魔法师数n,和n个数,表示每个魔法师的初始魔法值
输出一个数,在任意的对决中,最后只剩下来一名魔法师的最小的魔法值
示例1
输入: 4 [2,8,6,20]
输出: 2
解题思路
官方思路
我看了官方思路之后,做了很久没做出来.
然后,我就放弃了,两周后突然看到这道题,按照自己的思路一下子就做出来了.
官方的解释是,每次拿除了最小的那一个元素的其他元素去减掉最小的元素.
然后最后剩下来的就是答案.
第一个bug: 我按照这个思路强行写 , 没错肯定超时 , 比如: 一个例子:输入 2 [2,10000000];
这个时候如果用减法 , 百分之百无敌要超时 .
所以这个时候你想到了啥???
对没错 ! 用 % 代替 减法;
第二个bug: 我看到有一个超时的例子 , 是100000个数字 , 其中绝大部分是一样的 .
我再想想 , 这是道简单题 , 好的 , HashSet安排 , 直接过滤掉相同的数字 . 结果是 , 这十万个数 , 一轮循环就搞定了 !!
直接搞定 !! 看来还是要自己找规律 !! 多多熟悉一下集合!!
package alibaba;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* @Info:
* @Author: Tangxz
* @Date: 2020/09/06 20:00
*/
public class _42 {
public static void main(String[] args) throws IOException {
System.out.println(solution(5,new int[]{5,13,5,8,1000000000}));//100000
}
public static int solution(int n,int[] nums) {
Set<Integer> set1 = new HashSet<>();
Set<Integer> set2 = new HashSet<>();
for (int num:nums){
set1.add(num);
}
set1.forEach(System.out::println);
while (set1.size()>1) {
int min = Collections.min(set1);
Set<Integer> finalSet = set2; // 集合在遍历的过程中改变极易出现错误,这个集合是辅助集合
finalSet.add(min);
set1.forEach((num) -> {
if (num != min && num% min!=0) {
finalSet.add(num%min);
}
});
set1 = set2;
set1.forEach(System.out::println);
System.out.println("-------------");
set2 = new HashSet<>();
}
return Collections.max(set1);
}
}