从数组中删除连续元素的最有效方法? java - java

我正在尝试以最有效的方式解决此问题。

给定一个整数数组,请继续删除三个连续的相同整数,直到数组中不再有三个连续的相同元素,并返回这些元素出现的次数。

例如int [] {4,4,7,7,6,6,6,7,4}将返回3。当我们删除连续的6的int数组时,其int变为{4,4,7,7,7,7,4}在下一次迭代中,将删除连续的7,然后剩下{4,4,4},依此类推。

int [] {3,4,4,5,5,3}将返回0。

我已经尝试了使用不同集合的十多次,但是有人说我的代码需要很多操作,而且速度太慢。所以我只想使用数组,但被卡住了。这是我的代码:

    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,以搜索下一个三元组。
  • 如您所见,数组永远不会被修改,我们只是将索引值添加到数组中。与简单地修改数组并重试相比,这需要更多的代码,但是新代码的运行速度更快,因为我们不必在周围复制数组元素。

    祝你好运代码。 ?

    Java:正则表达式模式匹配器是否有大小限制? - java

    我的模式类似于OR:“word1 | word2 | word3”我大约有800个字。可能有问题吗? 参考方案 您仅受记忆和理智的限制。 :)

    Java:线程池如何将线程映射到可运行对象 - java

    试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

    Java:我可以在Hashmaps中使用数组吗? - java

    我可以在Hashmaps中使用数组吗?如果是这样,则声明这种哈希图的确切语法是什么?谢谢 参考方案 数组也是对象。甚至像int[]这样的原始数组。Map<String,String[]> map = new HashMap<String,String[]>();

    JAVA:字节码和二进制有什么区别? - java

    java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

    java:继承 - java

    有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…