我被要求进行HackerRank代码测试,我被问到的练习是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,2,2,2,1,1,2,2和34;
- 此切片的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;
}
}
答案 0 :(得分:0)
这是我在Java中的答案,它通过了所有HackerRank测试用例。如果您发现错误,请随时发表评论。
{{1}}
答案 1 :(得分:-1)
根据OP
的要求,这是一个python解决方案def solution(arr):
if (len(arr) <= 2): print arr
lres = 0
rres = 0
l = 0
r = 1
last = arr[1]
prev = arr[0]
while(r <= len(arr)-1):
if prev != last:
if arr[r] == prev:
prev = last
last = arr[r]
elif arr[r] != last:
l = r-1
while(arr[l-1] == last):
l -= 1
last = arr[r]
prev = arr[r-1]
else:
if arr[r] != prev:
last = arr[r]
if r - l > rres-lres:
rres = r
lres = l
r += 1
print arr[lres:rres+1]
对于当前细分,我们假设last
是最后添加的值,prev
是细分中的第二个不同值。 (最初他们可能是平等的。)
让我们将指针l
和r
保持在当前细分的左右两端,最多有两个不同的元素。我们假设我们考虑元素arr[r]
。
如果当前细分[l,r-1]
仅包含一个不同的元素,我们可以安全地添加arr[r]
,可能会更新last
和prev
。
现在,如果arr[r]
等于last
,那么我们就不需要做任何事情了。如果arr[r]
等于prev
,我们需要交换prev
和last
。如果它与这两者都不相等,我们需要更新l
左指针,从r-1
追溯到我们找到一个不等于last
的元素,然后更新{{ 1}}和last
。