这取决于定义什么是中间元素
假设中间元素是放在中间索引的那个,你应该使用List/ArrayList的方法E remove(int index)。
您可能希望将删除限制在输入列表大小为奇数的情况下。
public static void removeMid(ArrayList<Integer> o) {
if (o.size() > 1 && o.size() % 2 != 0) {
int removed = o.remove(o.size() / 2);
System.out.println("removed element: " + removed);
} else {
System.out.println("no middle element to remove is available");
}
}
如果你需要移除一个中间值,你可以对输入列表进行排序,然后像之前一样移除中间索引处的一个元素:
public static void removeMidValue(ArrayList<Integer> o) {
Collections.sort(o);
removeMid(o);
}
更新
递归解决方案包括找到min 和max 元素,删除它们,递归调用以从剩余列表中删除中间值,并在从递归调用返回时恢复min 和max 值。递归的退出条件是剩余列表仅包含一个要删除的元素。
要解决的另一点是如何恢复 min 和 max 元素 - 可以选择在删除/恢复元素时使用它们的索引,或者只是添加 min 和max 值返回列表从而改变初始顺序。
话虽如此,保持顺序的递归解决方案可能如下:
public static void removeMidRecursive(ArrayList<Integer> o) {
System.out.println("recursive: " + o);
if (o.size() % 2 == 0) {
System.out.println("list size is even, no middle element to remove");
} else if (o.size() == 1) {
int mid = o.remove(0);
System.out.println("removed mid element: " + mid);
} else {
// find indexes of min and max elements
int minId = 0;
int maxId = 0;
for (int i = 1; i < o.size(); i++) {
int val = o.get(i);
if (val < o.get(minId)) {
minId = i;
} else if (val >= o.get(maxId)) {
maxId = i;
}
}
// sort the indexes
int tMin = Math.min(minId, maxId);
int tMax = Math.max(minId, maxId);
// start removing from bigger index and store the value
// using `E remove(int index)`
Integer atMax = o.remove(tMax);
// System.out.printf("removed o[%d]=%d%n", tMax, atMax);
Integer atMin = o.remove(tMin);
// System.out.printf("removed o[%d]=%d%n", tMin, atMin);
removeMidRecursive(o);
// restore the values by insertig at appropriate index with a correction
if (tMin > 0) o.add(tMin - 1, atMin); else o.add(0, atMin);
if (tMax > 0) o.add(tMax - 1, atMax); else o.add(0, atMax);
System.out.println("restored: " + o);
}
}
测试:
ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(3, 5, 1, 1, 7, 6, 7));
System.out.println(arr);
removeMidRecursive(arr);
System.out.println(arr);
System.out.println("------------------");
arr = new ArrayList<>(Arrays.asList(6, 4, 1, 4, 2, 1, 4));
System.out.println(arr);
removeMidRecursive(arr);
System.out.println(arr);
输出
[3, 5, 1, 1, 7, 6, 7]
recursive: [3, 5, 1, 1, 7, 6, 7]
recursive: [3, 5, 1, 7, 6]
recursive: [3, 5, 6]
recursive: [5]
removed mid element: 5
restored: [3, 6]
restored: [3, 1, 7, 6]
restored: [3, 1, 1, 7, 6, 7]
[3, 1, 1, 7, 6, 7]
------------------
[6, 4, 1, 4, 2, 1, 4]
recursive: [6, 4, 1, 4, 2, 1, 4]
recursive: [4, 4, 2, 1, 4]
recursive: [4, 4, 2]
recursive: [4]
removed mid element: 4
restored: [4, 2]
restored: [4, 2, 1, 4]
restored: [6, 1, 4, 2, 1, 4]
[6, 1, 4, 2, 1, 4]
不保持原顺序的递归移除要简单得多,而且是使用另一个List的方法boolean remove(Object item):
public static void removeMidAndShuffle(ArrayList<Integer> o) {
if (o.size() % 2 == 0) {
System.out.println("list size is even, no middle element to remove");
} else if (o.size() == 1) {
int mid = o.remove(0);
System.out.println("removed mid element: " + mid);
} else {
Integer min = Integer.MAX_VALUE;
Integer max = Integer.MIN_VALUE;
for (Integer x : o) {
min = Math.min(min, x);
max = Math.max(max, x);
}
o.remove(min);
o.remove(max);
removeMidAndShuffle(o);
o.add(min);
o.add(max);
}
}
它的输出:
[3, 5, 1, 1, 7, 6, 7]
removed mid element: 5
[3, 6, 1, 7, 1, 7]
---------
[6, 4, 1, 4, 2, 1, 4]
removed mid element: 4
[2, 4, 1, 4, 1, 6]