【发布时间】:2025-12-20 07:15:12
【问题描述】:
我需要帮助来解决 Google 的 Foobar 挑战的第二级。
指挥官 Lambda 使用自动算法将奴才随机分配给任务,以使她的奴才保持警觉。但是你已经注意到算法中的一个缺陷——它最终会循环回到自身,因此它不会在迭代时分配新的 minions,而是陷入一个值循环,因此相同的 minions 最终会重复执行相同的任务并且再次。您认为向指挥官 Lambda 证明这一点将有助于您为下一次晋升提供依据。
你已经算出算法有如下过程:
1) 从一个随机的 minion ID n 开始,它是一个长度为 k 的非负整数,以 b 为底
2) 将 x 和 y 定义为长度为 k 的整数。 x 的 n 位按降序排列,y 的 n 位按升序排列
3) 定义 z = x - y。如有必要,向 z 添加前导零以保持长度 k
4) 赋值n = z 得到下一个minion ID,返回步骤2
例如,给定 minion ID n = 1211, k = 4, b = 10, 那么 x = 2111, y = 1112 and z = 2111 - 1112 = 0999. 那么下一个 minion ID 将是 n = 0999 并且算法再次迭代:x = 9990、y = 0999 和 z = 9990 - 0999 = 8991,依此类推。
根据 n、k(从 n 派生)和 b 的值,算法在某些时候会达到一个循环,例如通过达到一个常数值。例如,从 n = 210022, k = 6, b = 3 开始,算法将到达值的循环 [210111, 122221, 102212],无论它继续迭代多少次,它都将停留在这个循环中。从 n = 1211 开始,例程将到达整数 6174,并且由于 7641 - 1467 是 6174,因此无论迭代多少次,它都将保持该值。
给定一个 minion ID 作为字符串 n,表示长度为 k 的非负整数,以 b 为底,其中 2
测试用例:
Solution.solution("1211", 10) 返回 1
Solution.solution("210022", 3) 返回 3
这是我的代码:
import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
public static int solution(String n, int b) {
int k = n.length();
String m = n;
ArrayList<String> minionID = new ArrayList<>();
while (!minionID.contains(m)) {
minionID.add(m);
char[] s = m.toCharArray();
Arrays.sort(s);
int y = Integer.parseInt(toString(s));
int x = Integer.parseInt(reverseString(s));
if (b == 10) {
int intM = x - y;
m = Integer.toString(intM);
} else {
int intM10 = ((int) Integer.parseInt(toBase10(x,b))) - ((int) Integer.parseInt(toBase10(y, b)));
m = toBaseN(intM10, b);
}
m = addLeadingZeros(k, m);
}
System.out.println(minionID);
return minionID.size() - minionID.indexOf(m);
}
private static String toBaseN (int intBase10, int b) {
int residual = intBase10;
ArrayList<String> digitsBaseN = new ArrayList<>();
while (residual >= b) {
int r = residual % b;
digitsBaseN.add(Integer.toString(residual));
residual = (residual - r) / b;
}
digitsBaseN.add(Integer.toString(residual));
StringBuilder reverseDigits = new StringBuilder();
for (int i = digitsBaseN.size() -1; i >= 0; i--) {
reverseDigits.append(digitsBaseN.get(i));
}
return reverseDigits.toString();
}
private static String toBase10 (int intBaseN, int b) {
int[] xArr = new int[Integer.toString(intBaseN).length()];
int count = 0;
for (int i = xArr.length - 1; i >= 0; i--) {
xArr[count] = Integer.toString(intBaseN).charAt(i) - '0';
count++;
}
int yBase10 = 0;
for(int i = 0; i < xArr.length; i++) {
yBase10 += xArr[i] * (Math.pow(b, i));
}
return Integer.toString(yBase10);
}
public static String toString(char[] arr) {
StringBuilder newString = new StringBuilder();
for (char c : arr) {
newString.append(c);
}
if (newString.toString().contains("-")) {
newString.deleteCharAt(0);
}
return newString.toString();
}
public static String reverseString(char[] arr) {
StringBuilder newString = new StringBuilder();
for (int i = arr.length - 1; i >= 0; i--) {
newString.append(arr[i]);
}
if (newString.toString().contains("-")) {
newString.deleteCharAt(newString.length()-1);
}
return newString.toString();
}
public static String addLeadingZeros(int k, String z) {
if (k > z.length()) {
String zeros = "";
for (int i = 0; i < (k - z.length()); i++) {
zeros += "0";
}
zeros += z;
return zeros;
}
return z;
}
它只适用于十个测试用例中的三个
【问题讨论】:
-
输入
n有什么限制,可以有多少位? -
它没有告诉我长度的输入限制
-
失败的测试用例报告了哪些类型的错误?
-
NumberFormatExceptionError 对于“基数”不是 10 的情况。