Меня попросили пройти тест кода HackerRank, и задание, которое я попросил, - это Max Common Array Slice. Проблема заключается в следующем:Как улучшить алгоритм для Max Common Array Slice?
Вам предоставляется последовательность из n целых чисел a0, a1,. , , , an-1 и задача состоит в том, чтобы найти максимальный срез массива, который содержит не более , чем два разных числа.
Вход 1:
[1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8]
Результат 1: Ответ 10 потому что срез массива (0, 9) является самым большим фрагментом массива с не более чем двумя разными числами.
- В этом фрагменте 10 предметов, которые являются «1, 1, 1, 2, 2, 2, 1, 1, 2, 2».
- 2 разные числа для этого среза равны 1 и 2.
вход 2:
[53, 800, 0, 0, 0, 356, 8988, 1, 1]
Результат 2: Ответ равен 4, потому что срез (1, 4) является наибольшим фрагментом массива с не более чем двумя разными числами. Срез (2, 5) также будет действительным, и будет по-прежнему дает результат 4.
- Есть 4 элементов в этом срезе, которые являются «800,0,0,0».
- 2 разных числа для этого среза являются 800 и 0.
Максимального срез общего массива массива, который содержит реализацию не более два различных номера в Java принимает запятые массива чисел из STDIN и вывод записывается обратно в консоль.
Реализация, которую я предоставляю (ниже), работает, однако 3 тайм-аута контрольных случаев в HR. Очевидно, что HR скрывает тестовые примеры, поэтому я не смог точно определить условия, в которых был установлен тайм-аут, или даже продолжительность таймаута. Я не удивлен таймаутом, хотя, учитывая асимптотическую сложность моего решения. Но мой вопрос: как можно улучшить мое решение?
Заранее благодарим всех, кто поможет!
import java.io.*;
import java.lang.*;
import java.util.*;
import java.util.stream.*;
public class Solution {
public static void main(String args[]) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
List<Integer> inputSequence = parseIntegerSequence(line);
int largestSliceSize = calculateLargestSlice(inputSequence);
System.out.println(largestSliceSize);
}
private static List<Integer> parseIntegerSequence(String input) {
if (input == null)
return new ArrayList();
return Arrays.asList(input.split("\\s*,\\s*"))
.stream()
.filter(item -> item.matches("^\\s*-?[0-9]+\\s*$"))
.map(item -> Integer.parseInt(item))
.collect(Collectors.toList());
}
private static int calculateLargestSlice(List<Integer> inputSequence) {
Map<Integer, Integer> temporaryMap = new HashMap<>();
int result = 0;
int startIndex = 0;
int uniqueItemCount = 0;
Integer[] array = inputSequence.toArray(new Integer[inputSequence.size()]);
while (startIndex < array.length) { // loop over the entire input sequence
temporaryMap.put(array[startIndex], startIndex);
uniqueItemCount++;
for (int j = startIndex + 1; j < array.length; j++) {
if (temporaryMap.get(array[j]) == null) {
if (uniqueItemCount != 2) {
temporaryMap.put(array[j], j);
uniqueItemCount++;
if (j == array.length - 1) {
result = Math.max(result, j - startIndex + 1);
startIndex = array.length;
break;
}
} else {
result = Math.max(result, j - startIndex);
int item = array[j-1];
int firstFoundIndex = 0;
for(int k=j-1; k>=0; k--)
{
if(array[k] != item)
{
firstFoundIndex = k+1;
break;
}
}
startIndex = firstFoundIndex;
temporaryMap.clear();
uniqueItemCount = 0;
break;
}
} else if (temporaryMap.get(array[j]) != null) {
if (j == array.length - 1) {
result = Math.max(result, j - startIndex + 1);
startIndex = array.length;
break;
}
}
}
}
return result;
}
}
Пожалуйста, объясните свой алгоритм на простом языке с псевдонимом. –
Этот вопрос больше подойдет для http://codereview.stackexchange.com/ –
только двух методов указателя 'O (n)' probem – Yerken