繁体   English   中英

在Java中删除Arraylist中的元素对

[英]Removing pairs of elements in an Arraylist in Java

我知道以前曾问过类似的问题,但是它们通常会从Arraylist中删除所有指定的元素。

我需要做的是从我的ArrayList中删除一对值(如果一个数字出现3次,它将删除该元素的2个副本并保留其中的1个)。 更一般而言,如果一个数字出现奇数次,则离开1;如果一个数字出现偶数次,则将其全部删除。 因此,如果我的Arraylist是这样的

[5、4、3、3、2、1、2、3、1],

输出将是

[5,4,3]

由于数字“ 2”出现两次,因此已完全删除。 与数字“ 1”相同。 但是由于数字“ 3”出现了三次,因此将其中之一留在ArrayList中,因为我只想成对删除数字。

我根本不在乎订购,因为无论如何我都会重新订购。

有人对此有任何建议吗? 我认为我可以使用for循环反复比较每个值,但这似乎效率不高,因此我很好奇是否有更好的方法。

谢谢!

如果允许您对arraylist进行排序,这将变得非常简单。

public void removePairedElements(ArrayList<Integer> a){

    Collections.sort(a); //Sort a

    int i = 0;
    while(i < a.size() - 1){
      //Check if i and i+1 are the same element. If so, remove both
      if(a.get(i).equals(a.get(i+1))){
        //Remove i twice - effectively removes i and i+1
        a.remove(i);
        a.remove(i);

        //Move i *back* one index, which is equivalent to 
        //moving forward one because we just removed two elements.
        //Prevent i from becoming negative though.
        i = Math.max(0, (i - 1));
      }
      else{
        i++;
      }
    }
}

O(n log n)时间和O(1)空间。 可能是最干净的答案。 如果不允许更改数组列表的顺序,则必须做其他事情,否则应该可以。

您可以使用地图作为助手。

  • 遍历ArrayList
  • 假设列表的第i个元素包含数字n。
  • 如果map.containsKey(n),则map.get(n)是上一次出现的n在列表中的位置。
    • 从列表中删除第i个元素和第map.get(n)个元素。
    • 从地图中删除键n。
  • 其他
    • map.put(n,i)

实施说明:

不要使用增强的for循环来遍历列表(因为它不允许删除元素)。 遍历列表的索引。 这将允许您按元素索引删除元素(但请记住,当删除第i个元素时,先前的i + 1元素将成为新的第i个元素)。

我认为您最好的选择是对列表进行排序。

然后,倒退,如果您看到一个相同的整数,则在跟踪当前整数的总数的同时删除整数。

如果您看到的总数是偶数,则不会删除上一次出现的次数。 如果您看到总数奇怪的数字,则将删除最后一次出现的数字。

public void removePairElementsFrom(Arraylist<Integer> myArrayList)
{
    if (myArrayList == null)
    {
        return null;
    }

    int arrayLength = myArrayList.size();

    if (arrayLegnth == 1)
    {
        return myArrayList;
    )

    Collections.sort(myArrayList);

    int lastSeenInt = myArrayList.get(arrayLength - 1);
    int lastSeenIntCount = 1;

    for (int i = arrayLength - 2; i >= 0; --i)
    {
        if (myArrayList[i] == lastSeenInt)
        {
            myArrayList.remove(i+1);
            ++lastSeenIntCount;
        }
        else
        {
            if ((lastSeenIntCount % 2) == 0)
            {
                myArrayList.remove(i+1);
            }

            lastSeenInt = myArrayList.get(i);
            lastSeenIntCount = 1;
        }
    }

    if ((lastSeenIntCount % 2) == 0)
    {
        myArrayList.remove(0);
    }
}

请享用 :)

编写一个方法removeBadPairs,该方法接受一个整数ArrayList并删除列表中所有相邻的整数对(如果该对的左元素大于该对的右元素)。 每对的左元素是列表中的偶数索引,而每对的右元素是列表中的奇数索引。 例如,假设一个名为list的变量存储以下元素值:

[3, 7, 9, 2, 5, 5, 8, 5, 6, 3, 4, 7, 3, 1]

我们可以将此列表视为成对的序列:(3,7),(9,2),(5,5),(8,5),(6,3),(4,7),(3 ,1)。 对(9、2),(8、5),(6、3)和(3、1)是“坏的”,因为左元素大于右元素,因此应删除这些对。 因此,调用removeBadPairs(list); 将更改列表以存储以下元素值:

[3, 7, 5, 5, 4, 7] 

如果列表的长度为奇数,则最后一个元素不是对的一部分,也被视为“错误”; 因此,应使用您的方法将其删除。 如果传入一个空列表,则在调用结束时该列表仍应为空。 您可以假定传递的列表不为空。 尽管您可以根据需要创建任意数量的简单变量,但您不得使用任何其他数组,列表或其他数据结构来解决此问题。

如果由于迭代器而使用For循环从列表的开头开始,则会出现错误。 所以我有另一种方法。

class RemoveBadPairs {    
    Public Static void main() {
        ArrayList numbersList = new ArrayList();
        numberslist={3,7,9,2,5,5,8,5,6,3,4,7,3,1,7};   
        System.out.println("Original List...");
        for (e in : numbersList) {
            System.out.print("{0},", e);
        }
        if (((numbersList.Count % 2)!= 0)) {
            numbersList.RemoveAt((numbersList.Count - 1));
        }
        for (int i = (numbersList.Count - 1); (i <= 0); i = (i + -2)) {
            if ((numbersList[i] < numbersList[(i - 1)])) {
                numbersList.RemoveRange((i - 1), 2);
            }   
        }
        System.out.println("Final List...");
        for (e in : numbersList) {
            System.out.print(","+ e);
        }
    }
}

我希望这会起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM