我想迭代一个链表并递归删除每个第三个元素。
如果到达列表的末尾,我会对链接列表中剩余的元素执行相同的调用。我这样做,直到链接列表中只剩下一个元素。
我的解决方案没有按预期工作:
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);
}
}
答案 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]