如何递归删除链表中的每个第三个元素?

时间:2017-12-09 19:51:49

标签: java

我想迭代一个链表并递归删除每个第三个元素。

如果到达列表的末尾,我会对链接列表中剩余的元素执行相同的调用。我这样做,直到链接列表中只剩下一个元素。

我的解决方案没有按预期工作:

import java.util.LinkedList;
import java.util.List;

    public class test {

    public static void main(String[] args) {
        int randomNumber = (int )(Math.random() * 50 + 1);
        List<Integer> testList = new LinkedList<Integer>();

        for (int i = 1; i <= randomNumber; i++)
        {
            testList.add(i);
        }
    }
        public void removeElements(List testList)
        {
           for(int i = 0; i < testList.size();i++){
                if(i % 3 == 0){
                    testList.remove(i);
                }
            }
            if(testList.isEmpty()){
                return;
            }
            removeElements(testList-1);
        }
 }

4 个答案:

答案 0 :(得分:4)

如果您以递归方式执行此操作,则无需进行迭代。将问题简化为一次迭代并将其应用于当前状态,然后将其应用于列表的其余部分。它似乎不是一个节点类,因此必须使用索引来完成。

删除第三个元素意味着保留当前的两个元素并删除它们之后的元素。我们还必须考虑到该列表将会转移&#39;当我们删除一个,所以我们不必在删除后前进。下一个当前的&#39;将与我们删除的索引相同。

public void removeElements(List list, int current) {
   int removeIndex = current + 2;     // remove the third element
   if (removeIndex >= list.size())    // if there isn't one, stop
      return;

   list.remove(removeIndex);          // if there is one, remove it
   removeElements(list, removeIndex); // continue with the rest of the list
}

为了避免总是必须准备好方法,你可以写第二个为你做的事情:

public void removeElements(List list) {
   removeElements(list, 0);
}

例如:

List<Integer> list = new LinkedList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
list.add(7);
list.add(8);
list.add(9);
list.add(10);

removeElements(list);

for (int x = 0; x < list.size(); x++)
   System.out.println(list.get(x));

// output: 1 2 4 5 7 8 10

由于您更新了要删除的第n个项目,因此可以通过修改添加到当前索引的值轻松更改此项目:

public void removeElements(List list, int current, int n) {
   int removeIndex = current + n - 1;    // remove the nth element
   if (removeIndex >= list.size())       // if there isn't one, stop
      return;

   list.remove(removeIndex);             // if there is one, remove it
   removeElements(list, removeIndex, n); // continue with the rest of the list
}

public void removeEverySecond(List list) {
   removeElements(list, 0, 2);
}

public void removeEveryThird(List list) {
   removeElements(list, 0, 3);
}

// etc.

答案 1 :(得分:0)

您正在从正在迭代的列表中删除项目。这使它变得脆弱。当迭代变大时,列表变小。这导致IndexOutOfBounds像错误。

创建列表副本并根据orinal上的迭代从副本中删除内容然后返回简化副本可能是个更好的主意。

答案 2 :(得分:0)

  

递归删除每第三个元素。

和代码

if(i % 3 == 0){
                testList.remove(i);
            }

看起来代码会删除第一个,然后每三个删除一次。你真的在期待什么?但是,如果您修复它,那么您将面临@GCP提到的问题

答案 3 :(得分:0)

package com.company;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        List<Integer> list = new LinkedList<>(Arrays.asList(1,2,3,4,5,6,7,8,9,10));

        removeRecursive(list);

        System.out.println("The elements that remained in the list are: " + list);

    }


   public static void removeRecursive(List<Integer> list){

        if (list.size() < 3)
           return;

       for (int i = 2; i < list.size(); i += 2) {
           System.out.println("Removing element " + list.remove(i) + " from the list.");
       }

       removeRecursive(list);

   }
}

好的,我在这里做的是:

我将LinkedList of Integers从1改为10,我调用递归方法,并在递归方法完成其工作后打印出列表的最终内容。

以递归方式:

我们将LinkedList of Integers作为参数,我们的基本情况是list.size()是否小于3(因为我们需要删除每个第3个元素),因为如果list少于3个元素,我们可以&#39;删除第3个(显然),然后我们从索引2处的元素循环(第三个元素)并删除它,我们每次循环结束时我们也增加 i 2,所以我们继续删除每个第3个元素直到我们到达列表的末尾。然后我们再次调用我们的递归方法,并将LinkedList与所有剩余元素一起传递,最终当列表大小小于3时,我们的递归方法就完成了。然后我们返回main并在完成所有内容后打印出列表中剩余的元素。

1,2,3,4,5,6,7,8,9,10列表的输出:

从列表中删除元素3.

从列表中删除元素6.

从列表中删除元素9。

从列表中删除元素4.

从列表中删除元素8。

从列表中删除元素5.

从列表中删除元素7.

从列表中删除元素10.

列表中剩余的元素是:[1,2]