【面试&算法】 42.最后的胜者

概述:
现在有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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值