Algorithm 具有2个唯一数字的最大连续子阵列的长度
我有一个数字数组,我想计算出由两个唯一数字组成的连续子数组的最大长度 例如,[2,3,4,3,2,2,4]将返回3,因为[3,2,2]的长度为3Algorithm 具有2个唯一数字的最大连续子阵列的长度,algorithm,vector,data-structures,Algorithm,Vector,Data Structures,我有一个数字数组,我想计算出由两个唯一数字组成的连续子数组的最大长度 例如,[2,3,4,3,2,2,4]将返回3,因为[3,2,2]的长度为3 [2, 4, 2, 5, 1, 5, 4, 2] would return 3. [7, 8, 7, 8, 7] would return 5. 编辑:我考虑过一个O(n^2)解决方案,从数组中的每个值开始,迭代直到看到第三个唯一值 for item in array: iterate until third unique element
[2, 4, 2, 5, 1, 5, 4, 2] would return 3.
[7, 8, 7, 8, 7] would return 5.
编辑:我考虑过一个O(n^2)解决方案,从数组中的每个值开始,迭代直到看到第三个唯一值
for item in array:
iterate until third unique element
if length of this iteration is greater than existing max, update the max length
return maxlength
然而,我不认为这是一个有效的解决方案。这可以通过O(n)实现。代码是用python3编写的o
和t
分别为一和二m
是最大值,c
是当前计数变量
a = [7, 8, 7, 8, 7]
m = -1
o = a[0]
t = a[1]
# in the beginning one and two are the first 2 numbers
c = 0
index = 0
for i in a:
if i == o or i == t:
# if current element is either one or two current count is increased
c += 1
else:
# if current element is neither one nor two then they are updated accordingly and max is updated
o = a[index - 1]
t = a[index]
m = max(m, c)
c = 2
index += 1
m = max(m, c)
print(m)
我们可以使用双指针技术在O(n)运行时复杂性中解决这个问题。这两个指针,例如
startPtr
和endPtr
将表示数组中的范围。我们将保持此范围[startPtr,endPtr]
,使其包含的唯一编号不超过2个。我们可以通过跟踪2个唯一数字的位置来实现这一点。我的C++实现如下:
int main()
{
int array[] = {1,2,3,3,2,3,2,3,2,2,2,1,3,4};
int startPtr = 0;
int endPtr = 0;
// denotes the size of the array
int size= sizeof(array)/sizeof(array[0]);
// contain last position of unique number 1 in the range [startPtr, endPtr]
int uniqueNumPos1 = -1; // -1 value represents it is not set yet
// contain last position of unique number 2 in the range [startPtr, endPtr]
int uniqueNumPos2 = -1; // -1 value represents it is not set yet
// contains length of maximum continuous subarray with 2 unique numbers
int ans = 0;
while(endPtr < size) {
if(uniqueNumPos1 == -1 || array[endPtr] == array[uniqueNumPos1]) {
uniqueNumPos1 = endPtr;
}
else {
if(uniqueNumPos2 == -1 || array[endPtr] == array[uniqueNumPos2]) {
uniqueNumPos2 = endPtr;
}
else {
// for this new third unique number update startPtr with min(uniqueNumPos1, uniqueNumPos2) + 1
// to ensure [startPtr, endPtr] does not contain more that two unique
startPtr = min(uniqueNumPos1, uniqueNumPos2) + 1;
// update uniqueNumPos1 and uniqueNumPos2
uniqueNumPos1 = endPtr -1;
uniqueNumPos2 = endPtr;
}
}
// this conditon is to ensure the range contain exactly two unique number
// if you are looking for the range containing less than or equal to two unique number, then you can omit this condition
if (uniqueNumPos1 != -1 && uniqueNumPos2 !=-1) {
ans = max( ans, endPtr - startPtr + 1);
}
endPtr++;
}
printf("%d\n", ans);
}
intmain()
{
int数组[]={1,2,3,3,2,3,2,3,2,2,2,1,3,4};
int startPtr=0;
int-endPtr=0;
//表示数组的大小
int size=sizeof(数组)/sizeof(数组[0]);
//包含范围[startPtr,endPtr]中唯一编号1的最后位置
int uniqueNumPos1=-1;//-1值表示尚未设置
//包含范围[startPtr,endPtr]中唯一编号2的最后位置
int uniqueNumPos2=-1;/-1值表示尚未设置
//包含具有2个唯一数字的最大连续子阵列的长度
int ans=0;
while(endPtr
感谢MBo指出错误
import java.util.Arrays;
import static java.lang.System.out;
class TestCase{
int[] test;
int answer;
TestCase(int[] test,int answer){
this.test = test;
this.answer = answer;
}
}
public class Solution {
public static void main(String[] args) {
TestCase[] tests = {
new TestCase(new int[]{2, 3, 4, 3, 2, 2, 4},3),
new TestCase(new int[]{2, 3, 3, 3, 3, 4, 3, 3, 2, 2, 4},7),
new TestCase(new int[]{1,2,3,3,4,2,3,2,3,2,2,2,1,3,4},7),
new TestCase(new int[]{2, 7, 8, 7, 8, 7},5),
new TestCase(new int[]{-1,2,2,2,2,2,2,2,2,2,2,-1,-1,4},13),
new TestCase(new int[]{1,2,3,4,5,6,7,7},3),
new TestCase(new int[]{0,0,0,0,0},0),
new TestCase(new int[]{0,0,0,2,2,2,1,1,1,1},7),
new TestCase(new int[]{},0)
};
for(int i=0;i<tests.length;++i){
int ans = maxContiguousArrayWith2UniqueElements(tests[i].test);
out.println(Arrays.toString(tests[i].test));
out.println("Expected: " + tests[i].answer);
out.println("Returned: " + ans);
out.println("Result: " + (tests[i].answer == ans ? "ok" : "not ok"));
out.println();
}
}
private static int maxContiguousArrayWith2UniqueElements(int[] A){
if(A == null || A.length <= 1) return 0;
int max_subarray = 0;
int first_number = A[0],second_number = A[0];
int start_index = 0,same_element_run_length = 1;
for(int i=1;i<A.length;++i){
if(A[i] != A[i-1]){
if(first_number == second_number){
second_number = A[i];
}else{
if(A[i] != first_number && A[i] != second_number){
max_subarray = Math.max(max_subarray,i - start_index);
start_index = i - same_element_run_length;
first_number = A[i-1];
second_number = A[i];
}
}
same_element_run_length = 1;
}else{
same_element_run_length++;
}
}
return first_number == second_number ? max_subarray : Math.max(max_subarray,A.length - start_index);
}
}
算法:
[2, 3, 4, 3, 2, 2, 4]
Expected: 3
Returned: 3
Result: ok
[2, 3, 3, 3, 3, 4, 3, 3, 2, 2, 4]
Expected: 7
Returned: 7
Result: ok
[1, 2, 3, 3, 4, 2, 3, 2, 3, 2, 2, 2, 1, 3, 4]
Expected: 7
Returned: 7
Result: ok
[2, 7, 8, 7, 8, 7]
Expected: 5
Returned: 5
Result: ok
[-1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, 4]
Expected: 13
Returned: 13
Result: ok
[1, 2, 3, 4, 5, 6, 7, 7]
Expected: 3
Returned: 3
Result: ok
[0, 0, 0, 0, 0]
Expected: 0
Returned: 0
Result: ok
[0, 0, 0, 2, 2, 2, 1, 1, 1, 1]
Expected: 7
Returned: 7
Result: ok
[]
Expected: 0
Returned: 0
Result: ok
- 因此,我们维护两个变量第一个\u编号和第二个\u编号,它们将保存这两个唯一的编号李> 正如你所知道的,为了得到最大的子数组长度,我们需要考虑很多子数组,它有2个唯一的元素。因此,我们需要一个指针变量,它将指向子数组的开始。在这种情况下,该指针是开始索引李>
- 当我们发现第三个数字不等于第一个或第二个时,任何子数组都会中断。因此,现在,我们通过执行i-start\u index来计算先前的子阵列长度(具有这两个唯一元素)
- 这个问题的棘手部分是如何获得下一个子数组的开始索引
- 如果您仔细观察,second\u number前一个子数组变为当前子数组的first\u number,而我们刚才遇到的third变为当前子数组的second\u number
- 因此,计算此第一个\u编号何时开始的一种方法是向后运行一个while循环,以获得该开始\u索引。但是如果有很多子阵需要考虑的话,那么这将使得算法O(n^2)
- 因此,我们维护一个名为same_element_run_length的变量,该变量只跟踪数字重复多少次的长度或频率,并在数字中断时进行更新。因此,start\u index在我们遇到第三个数字后,下一个子阵的开始索引变为start\u index=i-相同的元素运行长度
- 剩下的计算是不言自明的
- 时间复杂度:O(n),空间复杂度:O(1)
重复2个数字的最大长度是多少,直到我看到第三个唯一的数字,这意味着,在下面的示例中,你是如何得到5和3的,请澄清?我已经添加了我尝试过的方法。我得到了5,因为该数组中只有2个唯一的元素,所以我可以遍历整个数组(大小为5)。我想找出2个唯一元素的最大子数组的长度。我在前面的数组中得到了3,因为[2,4,2]或[5,1,5]都是长度为3的。我刚刚重命名了这个问题,以便更恰当地反映手上的问题。在第一个示例中,3,4,3不是返回3吗?a.index()的复杂度是多少?它是O(n),我的错。但是,由于我使用的是当前元素的索引,而不是在整个数组中搜索,因此不需要使用,并且可以使用O(1)中的索引变量来使用。请根据编辑答案尝试使用a=[2,7,8,7,8,7]
。解决方案错误。已修复,需要在退出循环后更新m,感谢反馈i