用于查找给定整数的最小Antiprime的更好算法

时间:2016-07-27 17:21:33

标签: java algorithm hashset

我在HackerRank上发现了这个问题,在那里我们应该找到最小的AntiPrime数字(正整数是antiprime,当且仅当它有比任何其他小于它自身的正整数更多的除数时)。

因此,如果用户输入5,那么最小的反抵押号码将是6,因为6的除数比任何数字b / w 1到5都多。

我的方法: - 在散列集中存储每个数字1到n的除数的数量,然后从n + 1检查具有比HashSet中的除数更多的除数的整数。

public static int send(int n)
    {
        HashSet hs = new HashSet() ;
        for(int i=1 ; i<=n ; i++)
        {
            hs.add(div(i)) ;
        }    
        for(int i= n+1 ; ; i++)
        {
            if(Collections.max(hs).compareTo(div(i)) < 0 )
            {
                return i ;
            }    
        }    
    }    
    public static int div(int n)
    {
        int ctr = 0 ;
        for(int i=1 ; i<=n ; i++)
        {
            if(n % i == 0)
                ctr++ ;
        }    
        return ctr ;
    }

逻辑运行完美,但在所有测试用例中它返回超时,因为我看到的复杂性是O(n ^ 2)。

所以,请建议我一个更好的算法,它可以在相对较短的时间内完成。

2 个答案:

答案 0 :(得分:1)

您可以使用Set<>数据结构,然后每次除数达到峰值时都可以存储(Antiprime数字)。然后,您可以调用ceiling()之类的内容来获取该数字中的下一个最大值,因此对于5,它会在6时间内返回O(logn)。此外,对于输出,使用StringBuilder并构建结果然后输出它。对我而言,它最初与System.out.println()无效,但结果是StringBuilder然后是append()。最后,在.toString()StringBuilder。作为参考,我在比赛中获得了第8名(超过2000+),所以它对我有用,然后变得完美。

答案 1 :(得分:1)

我在这里引用了评论中提到的修改:

public static int send(int n)
    {
        HashSet hs = new HashSet() ;
        for(int i=int(n/2)+1 ; i<=n ; i++)
        {
            hs.add(div(i)) ;
        }
        int markToBeat = Collections.max(hs);
        for(int i=n+1 ; ; i++)
        {
            if(div(i) > markToBeat )
            {
                return i ;
            }
        }    
    }    
    public static int div(int n)
    {
        int ctr = 0 ;
        for(int i=1 ; i<=sqrt(n) ; i++)
        {
            if(n % i == 0)
                ctr++ ;
        }    
        return ctr ;
    }