我之前已经问过类似的问题,但它们通常会从Arraylist中删除所有指定的元素。
我需要做的是从我的ArrayList中删除一对值(如果一个数字出现3次,它将删除该元素的2个副本并留下其中的1个)。更一般地说,如果出现一个数字,则奇数次数为1,如果出现一个数字偶数次则将它们全部删除。因此,如果我的Arraylist就是这样的话
[5,4,3,3,2,1,2,3,1],
输出将是
[5,4,3]
由于数字“2”出现两次,因此完全删除。与数字“1”相同。但由于数字“3”出现三次,它会将其中一个留在ArrayList中,因为我只想成对删除数字。
我根本不在乎订购,因为我还是要重新订购它。
有人对此有任何建议吗?我想我可以使用for循环来反复比较每个值,但它似乎效率低下,所以我很好奇是否有更好的方法。
谢谢!
答案 0 :(得分:2)
如果你被允许对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的顺序,则必须执行其他操作,否则这应该有效。
答案 1 :(得分:1)
您可以使用地图作为帮助。
实施说明:
不要使用增强的for循环迭代列表(因为它不允许删除元素)。迭代列表的索引。这将允许您通过索引删除元素(但请记住,当您删除第i个元素时,前一个i + 1元素将成为新的第i个元素。)
答案 2 :(得分:1)
我认为你最好的选择是对名单进行排序。
然后,向后,如果你看到同一个,同时跟踪当前整数的总数,则删除整数。
如果您看到偶数总数,则不会删除最后一次出现。 如果你看到一个奇怪的总数,你将删除最后一次出现。
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);
}
}
享受:)
答案 3 :(得分:0)
编写一个方法removeBadPairs,它接受一个整数的ArrayList并删除任何相邻的对 如果该对的左侧元素大于该对的右侧元素,则列表中的整数。每一双 left元素是列表中的偶数索引,每个对的右元素是列表中的奇数索引。 例如,假设名为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]
如果列表的长度为奇数,则最后一个元素不是一对的一部分,也被视为“坏”;这应该 因此,您的方法将删除。 如果传入空列表,则在调用结束时列表仍应为空。你可能会认为 传递的列表不为空。您不能使用任何其他数组,列表或其他数据结构来帮助您解决 这个问题,虽然你可以创建任意数量的简单变量。
答案 4 :(得分:0)
如果由于迭代器而使用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);
}
}
}
我希望这会奏效。