簡體   English   中英

如何遞歸刪除鏈表中的每個第三個元素?

[英]How to remove every third element from a linked list recursively?

我想迭代鏈表並遞歸刪除每個第三個元素。

如果到達列表的末尾,我會對鏈接列表中剩余的元素執行相同的調用。 我這樣做,直到鏈表中只剩下一個元素。

我的解決方案沒有按預期工作:

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);
        }
 }

如果你以遞歸方式進行,那么就不需要迭代了。 將問題簡化為一次迭代並將其應用於當前狀態,然后將其應用於列表的其余部分。 似乎沒有節點類,因此必須使用索引。

刪除第三個元素意味着保留當前的兩個元素並刪除它們之后的元素。 我們還必須考慮到,當我們刪除列表時,列表將“移位”,因此我們不必在刪除后向前推進。 下一個'當前'將與我們刪除的索引相同。

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.

您正在從正在迭代的列表中刪除項目。 這使它變得脆弱。 當迭代變大時,列表變小。 這導致IndexOutOfBounds像錯誤。

最好的做法是復制列表並根據orinal上的迭代從副本中刪除內容,然后返回簡化的副本。

遞歸刪除每第三個元素。

和代碼

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

看起來代碼首先刪除,然后每隔三個刪除一次 你真的在期待什么? 但是,如果您修復它,那么您將面臨@GCP提到的問題

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個元素,我們就無法刪除第3個元素(明顯),那么我們從元素循環索引2(第三元素),並刪除它,我們也增加了我們對 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]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM