将Java中ArrayList的remove()方法的时间复杂度由O(n)改为O(1)

将Java中ArrayList的remove()方法的时间复杂度由O(n)改为O(1)。

一、ArrayList的概述

1、底层实现原理

ArrayList的底层是通过动态数组的数据结构实现的。动态数组的默认长度是10,ArrayList会根据实际的需要动态的调整数组容量,将数组长度扩容为原数组长度的1.5倍。

2、删除数组元素

为什么remove()方法的时间复杂度是O(n)呢?
因为ArrayList的元素都是存储在数组里,而数组是一段连续的内存,当删除数组中的某一个元素,则需要该元素后面的所有元素向前移动一个位置。例如数组中元素是[1,2,3,4,5],删除元素3,则元素3后面的元素4需要从索引位置3移动到索引位置2,以此类推。这样删除一个元素,其后元素移动的时间复杂度就是O(n)。

二、交换元素 + HashMap 实现O(1)。

1、算法思路

①先创建一个HashMap,键是数组中元素,值是该元素在数组中的索引。
②当需要删除一个元素的时候,先去HashMap里面查找该元素对应的索引,然后将该元素交换到数组的末尾删除。
③每次把需要删除的元素交换到数组末尾删除,这样就不需要再移动元素了,只需要交换一次元素,时间复杂度从O(n)降为了O(1),思路有木有很巧妙?
④需要特别注意的是,在每次交换元素以后,需要将原来末尾元素在HashMap中的位置做一次更新,否则下一次删除的就是上一次交换之前的末尾元素了。

2、代码实现

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ListTest {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(3);
        list.add(5);
        list.add(7);
        System.out.println(list);//[1, 3, 5, 7]
        Map<Integer,Integer> map = new HashMap<>();
        //1、将list中元素及其索引存放进map
        for (int i = 0; i < list.size(); i++) {
            map.put(list.get(i),i);
        }
        System.out.println(map);//{1=0, 3=1, 5=2, 7=3}

        //2、将删除元素与末尾元素交换
        int val = 3;//3是需要删除的元素
        int tailIndex = list.size() - 1;//tailIndex是末尾元素的索引
        int removeIndex = map.get(val);//removeIndex是要删除元素的索引

        //交换元素
        int temp = list.get(tailIndex);
        list.set(tailIndex,val);
        list.set(removeIndex,temp);

        //交换结果
        System.out.println(list);//[1, 7, 5, 3]
        //注意:需要在map中更新此时temp的索引
        map.put(temp,removeIndex);
        System.out.println(map);//{1=0, 3=1, 5=2, 7=1}
        //删除末尾元素
        list.remove(tailIndex);
        map.remove(val,removeIndex);//将删除元素的键值对从map删除

        System.out.println(list);//[1, 7, 5]
        System.out.println(map);//{1=0, 5=2, 7=1}
    }
}

三、总结

通过这个代码事例的学习,在刷题的过程一定要注重细节,对于每个方法的细节要深入剖析。欢迎大家与小赵同学讨论交流,可以点赞关注私信。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小赵同学-

非常感谢你!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值