TJKT:
私はこの問題を解決しようとしています:
正の整数の配列、および整数を考えるとY、あなたは最大で交換するために許可されているYの小さい方の値を持つ配列要素。あなたの目標は、可能な限り同一の値の大Aのサブセットとしてで終わるための配列のためです。この最大のサブセットのサイズを返します。
配列はもともと昇順にソートされていますが、ないない、そのプロパティを維持する必要があります。
したがって、たとえば、アレイは[10,20,20,30,30,30,40,40,40]であり、場合Y = 3次の3つの40代を置き換えることによって6つの1930を得ることができるので、結果は、6であるべきです30代で。配列は[20,20,20,40,50,50,50,50]とした場合Y = 2あなたが20代と50代のうちの2つを置き換えることにより、5、20代を得ることができるので、その結果は、5にする必要があります。
以下は、O(nlogn)時間計算量を持つ私のソリューションです。私はさらに、このソリューションを最適化することができる場合(その権利がある?)私は疑問に思いますか?
前もって感謝します。
public class Nails {
public static int Solutions(int[] A, int Y) {
int N = A.length;
TreeMap < Integer, Integer > nailMap = new TreeMap < Integer, Integer > (Collections.reverseOrder());
for (int i = 0; i < N; i++) {
if (!nailMap.containsKey(A[i])) {
nailMap.put(A[i], 1);
} else {
nailMap.put(A[i], nailMap.get(A[i]) + 1);
}
}
List < Integer > nums = nailMap.values().stream().collect(Collectors.toList());
if (nums.size() == 1) {
return nums.get(0);
}
//else
int max = nums.get(0);
int longer = 0;
for (int j = 0; j < nums.size(); j++) {
int count = 0;
if (Y < longer) {
count = Y + nums.get(j);
} else {
count = longer + nums.get(j);
}
if (max < count) {
max = count;
}
longer += nums.get(j);
}
return max;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String[] input = scanner.nextLine().replaceAll("\\[|\\]", "").split(",");
System.out.println(Arrays.toString(input));
int[] A = new int[input.length - 1];
int Y = Integer.parseInt(input[input.length - 1]);
for (int i = 0; i < input.length; i++) {
if (i < input.length - 1) {
A[i] = Integer.parseInt(input[i]);
} else {
break;
}
}
int result = Solutions(A, Y);
System.out.println(result);
}
}
}
ruakh:
アレイが合理的に簡単で開始するようにソートされるので、O(N)溶液を(反復して)、その値を持っているどのように多くの要素をカウントするために、各個別の値について、であり、どのように多くの要素が(減算により)より高い値を有します。
public static int doIt(final int[] array, final int y) {
int best = 0;
int start = 0;
while (start < array.length) {
int end = start;
while (end < array.length && array[end] == array[start]) {
++end;
}
// array[start .. (end-1)] is now the subarray consisting of a
// single value repeated (end-start) times.
best = Math.max(best, end - start + Math.min(y, array.length - end));
start = end; // skip to the next distinct value
}
assert best >= Math.min(y + 1, array.length); // sanity-check
return best;
}