我正在尝试以最有效的方式解决此问题。
给出一个整数数组,继续删除三个连续的相同整数,直到数组中不再有三个连续的相同元素,并返回这些元素出现的次数。
例如int [] {4,4,7,7,6,6,6,7,4}将返回3。当我们删除连续的6时,int数组将变为{4,4,7,7,7,4 }在下一次迭代中,连续的7被删除,而我们剩下的是{4,4,4},依此类推。
int [] {3,4,4,5,5,3}将返回0。
我已经尝试使用不同的collection十多次,但有人说我的代码需要进行很多操作,而且速度太慢。所以我只想使用数组,但被卡住了。这是我的代码:
public static int getNumberOfRepetitions(int[] arr) {
int[] arr2 = new int[arr.length];
int counter= 0;
int index = 0;
for (int x= 0;x<arr.length;x++) {
if (x < arr.length - 2) {
if (arr[x] == arr[x + 2] && arr[x] == arr[x + 2]) {
counter++;
x = x + 2;
continue;
}
arr2[index] = arr[x];
index++;
}
if (x < arr.length - counter * 3) {
arr = arr2;
arr2 = new int[arr.length];
index = 0;
x = -1;
}
}
return counter;
}
该算法在数组上进行迭代,然后将项目添加到第二个数组中,如果存在连续元素,它将添加到计数器中并跳过它们。在最后一次迭代中,将arr设置为arr2,并且应重置for循环。
到目前为止,我还无法弄清楚如何终止代码,因此出现了无限循环。我是编程新手,不胜感激。
我被告知我的代码需要太多操作且速度太慢。
是正确的,因为您实际上可以执行此操作而无需修改数组。
由于这是您要完成的任务,所以我将向您展示如何做到这一点,而无需编写任何代码。
将计数器初始化为0,然后从数组的开头开始迭代。
找到下一个(第一个)三元组。如果找不到,就完成了,所以返回计数器值。
start
│ end
│ │
4,4,7,7,6,6,6,7,4
您找到了要删除的三元组,因此将计数器加1。
比较周围的值。首先比较前后的值。如果不同,请跳到步骤7。
start
│ end
│ │
4,4,7,7,6,6,6,7,4
└───────┘ are they equal?
当周围的值相等时,级联三元组有两种可能,一种是前一个额外的值,或后一个额外的值。如果之前/之后的额外值均与周围的值不同,请跳到步骤7。
start start
│ end │ end
│ │ O R │ │
4,4,7,7,6,6,6,7,4 4,7,6,6,6,7,7,4,4
└─┴───────┘ are they equal? └───────┴─┘ are they equal?
展开要删除的序列,然后返回到步骤3以重复级联搜索。
start start
│ end │ end
│ │ O R │ │
4,4,7,7,6,6,6,7,4 4,7,6,6,6,7,7,4,4
start start
│ end │ end
│ │ O R │ │
4,4,7,7,6,6,6,7,4 4,7,6,6,6,7,7,4,4
└─┴─────────────┘ └─────────────┴─┘ are they equal?
现在我们需要寻找一个更复杂的不相交的三元组。
12344433255666527
││└┴┘││││││││││ simple triplet found (step 2-3)
│└───┴┘││││││││ surrounding triplet found (step 4-6)
│ │││└┴┘││ another simple triplet found
│ │└┴───┘│ surrounding triplet found
└──────┴──────┘ disjoint triplet found
为此,我们需要跟踪先前删除的序列。
┌ prevStart
│ ┌ prevEnd
│ │ ┌ start
│ │ │ ┌ end
12344433255666527
└──────┴──────┘ are they equal?
如果上一个结束点是新开始点之前的2个位置,并且之前,之间和之后的3个值相等,那么我们发现了一个不相交的三元组。展开要删除的序列以包括先前的序列,当前序列和新的三元组,然后返回到步骤3以重复级联搜索。
您现在找到了要删除的部分,并将计数器增加了适当的次数,因此从end
位置开始,返回到步骤2,以搜索下一个三元组。
如您所见,数组从未修改,我们只是将索引值用于数组中。与简单地修改数组然后再试相比,这需要more code,但是新代码的运行速度更快,因为我们不必在周围复制数组元素。
祝您好运。 🙂
您的逻辑中有几处错误。而不是指出它们中的每一个,这是一种新方法:
private static int getNumberOfRepetitions(int[] arr) {
int[] arr2 = new int[arr.length];
int counter= 0;
int j = 0;
for (int i : arr) {
arr2[j++] = i;
if (j > 2) {
if (arr2[j - 1] == arr2[j - 2] && arr2[j - 1] == arr2[j - 3]) {
counter++;
j -= 3;
}
}
}
return counter;
}
这里,我们将元素一个接一个地添加到新数组中,并维护该数组的索引。当新数组中有3个元素时,比较最后3个元素。如果它们相等,则将索引('j')减3。
这里是递归方法的尝试。这类似于数组展平或找到匹配的括号,这很复杂,因为我们最多可以有三个元素将删除的部分连接在一起。