删除数组中以6结尾的两个或多个连续数字

时间:2018-07-03 07:53:48

标签: java arraylist collections

我已经尝试过了,但是它只能用于两个连续的数字,而不能用于两个以上的数字。请找到下面我尝试过的代码,并提出解决方案。

样本输入:

3 6 36 62 121 66 26 376 661 6

样本输出:

3 62 121 661 6

我的代码:

public static List<Integer> processArray(ArrayList<Integer> array) {
    int num=0;
    int prevnum=0;
   for(int i =0;i<array.size();i++) {
       num=array.get(i);
       if(i>0 && array.get(i-1)%10==6 && num%10==6) {
          array.remove(i-1);
          array.remove(i-1);
       }
   }
    return array;
}

3 个答案:

答案 0 :(得分:2)

如评论中所述。第一个解决方案恰好适用于您当前的用例。为了获得更灵活的解决方案,您可以使用以下代码段:

public static List<Integer> processList(List<Integer> list){
    int encountered = 0;
    for(ListIterator<Integer> it = list.listIterator(); it.hasNext(); ){
        int i = it.next();
        if(i % 10 == 6){
            encountered++;
        } else {
            encountered = 0;
        }
        if(encountered > 1){
            it.remove();
            if(encountered == 2){
                it.previous();
                it.remove();
            }
        }
    }
    return list;
}

它使用listIterator和一个计数器变量。这样,我们可以遍历列表,计算有6个,如果连续超过2个,则将其删除。

不使用迭代器时,一旦开始删除元素,它们将开始跳过元素。因为在索引处删除元素时,列表会缩短。因此,上面的元素1索引将滑入丢失的位置。然后,在下一步中增加索引时,您将跳过一个元素。


OLD

我建议使用迭代器和2个for循环来实现:

public static List<Integer> processList(List<Integer> list){
   for(Iterator<Integer> it = list.iterator(); it.hasNext(); ){
       for(int i = it.next(); i % 10 == 6 && it.hasNext(); i = it.next()){
           it.remove();
       }
   }
   return list;
}

第一个for循环照常迭代该列表,因为如果最后一个数字是6,则第二个将删除数字。

答案 1 :(得分:1)

从列表中删除元素时,我总是发现从末尾到开头向后处理列表是最简单的。这样,删除元素时唯一会移位的索引就是我已经完成的索引,因此我可以忽略移位。

public static void processArray(ArrayList<Integer> array) {
    // process from end of list backward
    int ix = array.size();
    while (ix > 0) {
        if (array.get(ix - 1) % 10 == 6) {
            // find beginning of run of numbers that end in 6
            int beginIx = ix - 1;
            while (beginIx > 0 && array.get(beginIx - 1) % 10 == 6) {
                beginIx--;
            }
            List<Integer> runOf6 = array.subList(beginIx, ix);
            if (runOf6.size() >= 2) {
                // delete entire run
                runOf6.clear();
            }
            ix = beginIx;
        }
        else {
            ix--;
        }
    }
}

演示:

ArrayList<Integer> list = new ArrayList<>(Arrays.asList(3, 6, 36, 62, 121, 66, 26, 376, 661, 6));
processArray(list);
System.out.println(list);

输出:

  

[3,62,121,661,6]

编辑:另一种选择是相反的方法:通过添加原始列表中不包含至少两个以6结尾的数字的元素来创建结果列表。作为一种特殊情况,如果原始列表的长度为0或1,则按原样返回它,因为其中不能有两个以6结尾的数字。否则,创建结果列表。遍历原始列表。对于每个元素,如果它以6结尾,并且在(至少)以6结尾的一侧也有邻居,则跳过它;否则,为0。否则将其添加到结果中。请注意不要检查第一个元素的左邻居或最后一个元素的右邻居,因为它们不存在,您会得到IndexOutOfBoundsException。如果您愿意,我会留给您探索这个选项。

答案 2 :(得分:0)

for循环中存在一个小问题。当for循环遍历Arraylist时,i的值将增加,而Arraylist的大小将减小,这是因为要删除以6结尾的元素。