如何提高我在下面编写的代码的性能来处理以下问题。
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号码
答案 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;
}