我有一个号码。这个数字有很多位数。我想写一个函数,它返回由该数字的某些数字组成的最大数字。获得最大数字时,数字的顺序不应改变。
int myFunction(int n, int cat){
...
return max;
}
如果n = 38462637
和cat = 3
该函数必须返回86637
,即如果cat = 3
函数预计会返回5位数字,则为8 - 3 = 5
。原始号码有5位数字的多种变体,但最大可能的数字是86637
。在这种情况下,最重要的要求是数字不应改变它们的位置。
答案 0 :(得分:2)
贪婪 - 选择答案中最左边的最大数字(如果有多个位置出现此数字,请选择最左边的位置)。如果数字不是0,则数字可以是最左边的数字,并且我们在其右边至少有n - cat - 1个数字。
之后使用相同的算法在该数字的位置右侧创建具有正好n - cat - 1
个数字的最大数字。继续迭代,直到你编号。只注意在第一次迭代后选择的数字可能为零(因为它们将不再是最终数字中最左边的数字)
编辑:使用上述算法的最佳解决方案 - 使用range minimum query计算每个连续数字位置可能的最高值。理论上,这可以使用线性预计算在每个查询和线性额外内存的恒定时间内完成,但算法非常复杂且难以实现,因此它只会为您提供非常大的n值的改进。我个人建议使用segment tree方法,这将导致O(n * log(n))时间复杂度。
答案 1 :(得分:0)
如果您有权访问代码,请将数字存储为带有分隔符(空格,逗号等)的字符串,然后使用字符串分隔符函数将每个数字(字符串字符)放入其自己的数组位置。解析字符串数组并生成整数数组。然后对阵列进行快速排序。完成后,取第一个X个整数,这就是你的数字。
答案 2 :(得分:0)
这可能有点过于复杂,但似乎有效:
public static int myFunction(int n, int cat) {
String numString = String.valueOf(n);
int finalLength = numString.length() - cat;
int[] positions = new int[finalLength];
StringBuilder answer = new StringBuilder();
for (int i = 0; i < finalLength; i++) {
for (int j = (i == 0 ? i : positions[i - 1] + 1); j <= numString.length() - finalLength + i; j++) {
if (positions[i] == 0 || numString.charAt(j) > numString.charAt(positions[i]) ) {
positions[i] = j;
}
}
answer.append(numString.charAt(positions[i]));
}
return Integer.parseInt(answer.toString());
}
[编辑] :没有所有String
废话的清洁版:
public static int myFunction(int n, int cat) {
List<Integer> digits = new ArrayList<Integer>();
int number = n;
while (number > 0) {
digits.add(number % 10);
number /= 10;
}
int finalLength = digits.size() - cat;
int lastIndex = digits.size();
int answer = 0;
for (int i = 0; i < finalLength; i++) {
int highestDigit = -1;
for (int j = lastIndex - 1; j >= finalLength - i - 1; j--) {
if (digits.get(j) > highestDigit) {
highestDigit = digits.get(j);
lastIndex = j;
}
}
answer = answer * 10 + highestDigit;
}
return answer;
}