提高绩效

时间:2014-09-07 15:41:31

标签: java algorithm

如何提高我在下面编写的代码的性能来处理以下问题。

N是圆圈中的对象数。我从0开始,然后进行M次跳跃,访问每个对象。如果一个物体被重复,那么我将停止并且所访问的物体的数量是我的答案

当前代码

// you can also use imports, for example:
 import java.util.*;

// you can use System.out.println for debugging purposes, e.g.
// System.out.println("this is a debug message");

class Solution {
    public int solution(int N, int M) {
        // write your code in Java SE 8

       int answer =1;
       HashMap<Integer , Integer> som = new HashMap<>();
       boolean check = true;
       int x =0;
       som.put(0,0);
       while(check){
            int  m = (x+ M) % N ;
            x = m;
            if(som.containsKey(x))
                check = false;
            else{
                som.put(x,0);
                answer++;
            }
       }
       return answer;
    }

不适合10 ^ 6号码

2 个答案:

答案 0 :(得分:3)

如果将N和M分解为素因子(即N = p [1] ^ e [1] * p [2] ^ e [2] * ...并且M = p [1] ^ f [1 ] * p [2] ^ f [2] ...)并考虑他们的指数e [1],e [2],...和f [1],f [2],...然后答案将be p [1] ^ max(0,e [1] - f [1])* p [2] ^ max(0,e [2] - f [2])....这在某种程度上是数学的,但应该是解决方案。

例如N = 120,M = 18。

N可写为2 ^ 3 * 3 ^ 1 * 5,M可写为2 ^ 1 * 3 ^ 2。现在我们的解决方案将是2 ^(3-1)* 5,等于20.

编辑:

背后的原因,为什么这样做是因为以下观察。如果你跳到一个已经访问过的地方,那么它必须是0.所以我们试图找到最小值x,使得x * m = 0(mod n)。我描述了如何通过考虑素因子找到x。实施留作练习。

答案 1 :(得分:1)

这样有点干净。

public int solution(int N, int M) {
    Set<Integer> set = new HashSet<>(N);
    int m = 0;
    int ans = 0;
    while(set.add(m)) {
       m = (m + M) % N ;
       ans++;
    }
    return ans;
}