学而不思则罔,思而不学则殆
【算法】【数组】删除数组中偶数下标的元素,返回奇数下标的元素
题目
删除ArratList中索引为偶数的节点
输入:
[1,2,3]
输出:
[2]
void removeItemsWithEvenIndex(ArrayList<Integer> list) {
}
注意:list既是输入,也是输出
解法一
思路:通过iterator迭代删除
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
空间复杂度:
O
(
1
)
O(1)
O(1)
static void removeItemsWithEvenIndex1(ArrayList<Integer> list) {
Iterator<Integer> iterator = list.iterator();
int index = 0;
while (iterator.hasNext()) {
iterator.next();
if (index % 2 == 0) {
iterator.remove();
}
index++;
}
}
解法二
思路:复制一份数据tmpList,把原有list列表清空,再把tmpList中奇数索引的元素加入到list中
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
static void removeItemsWithEvenIndex2(ArrayList<Integer> list) {
//copy一份
ArrayList<Integer> tmpList = new ArrayList<Integer>(list);
list.clear();
//获取偶数节点
for (int index = 0; index < tmpList.size(); index++) {
if (index % 2 != 0) {
list.add(tmpList.get(index));
}
}
}
解法三 - 双指针法
思路:双指针法标记,把奇数索引位置的元素前移。慢指针指向需要填充的位置,快指针遇到偶数索引跳过,奇数索引就把位置的元素复制到慢指针位置。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
static void removeItemsWithEvenIndex3(ArrayList<Integer> list) {
//
int index = 0;
for (int i = 0; i < list.size(); i++) {
if (i % 2 != 0) {
//奇数下标数据前移
list.set(index++, list.get(i));
}
}
//移除[index , list.size())的数据
if (list.size() > index) {
list.subList(index, list.size()).clear();
}
}
三种算法效率比较
算法\数量 | 100 | 1000 | 1w | 10w | 20w | 30w | 40w | 50w | 60w | 70w | 80w | 90w | 100w | 200w | 500w | 1000w | 2000w | 5000w |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
算法一 | 0 | 0 | 5 | 535 | 2220 | 4882 | 8842 | 13648 | 19537 | 26423 | 33950 | 44380 | 54999 | - | - | - | - | - |
算法二 | 0 | 0 | 1 | 5 | 5 | 6 | 8 | 8 | 9 | 10 | 10 | 10 | 13 | 16 | 140 | 38 | 72 | 224 |
算法三 | 0 | 0 | 1 | 5 | 5 | 5 | 5 | 6 | 7 | 7 | 7 | 8 | 8 | 10 | 18 | 24 | 39 | 87 |
随着数量的增加,第一种算法已经不能看了,直接砍掉。二三种时间差距不大,主要是空间消耗。
测试代码:
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 50000000; i++) {
list.add(i);
}
System.out.println(list.size());
ArrayList<Integer> list1 = new ArrayList<>(list);
ArrayList<Integer> list2 = new ArrayList<>(list);
ArrayList<Integer> list3 = new ArrayList<>(list);
long start = System.currentTimeMillis();
removeItemsWithEvenIndex3(list1);
long end = System.currentTimeMillis();
System.out.println(list1.size() + " " + (end - start));
start = System.currentTimeMillis();
removeItemsWithEvenIndex2(list2);
end = System.currentTimeMillis();
System.out.println(list2.size() + " " + (end - start));
start = System.currentTimeMillis();
removeItemsWithEvenIndex1(list3);
end = System.currentTimeMillis();
System.out.println(list3.size() + " " + (end - start));
System.out.println(list1.equals(list2));
System.out.println(list1.equals(list3));
}