JAVA学习-练习试用Java实现“O(1) 时间插入、删除和获取随机元素”

问题:

设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构。

注意: 允许出现重复元素。

insert(val):向集合中插入元素 val。
remove(val):当 val 存在时,从集合中移除一个 val。
getRandom:从现有集合中随机获取一个元素。每个元素被返回的概率应该与其在集合中的数量呈线性相关。
示例:

// 初始化一个空的集合。
RandomizedCollection collection = new RandomizedCollection();
// 向集合中插入 1 。返回 true 表示集合不包含 1 。
collection.insert(1);

// 向集合中插入另一个 1 。返回 false 表示集合包含 1 。集合现在包含 [1,1] 。
collection.insert(1);

// 向集合中插入 2 ,返回 true 。集合现在包含 [1,1,2] 。
collection.insert(2);

// getRandom 应当有 2/3 的概率返回 1 ,1/3 的概率返回 2 。
collection.getRandom();

// 从集合中删除 1 ,返回 true 。集合现在包含 [1,2] 。
collection.remove(1);

// getRandom 应有相同概率返回 1 和 2 。
collection.getRandom();

解答思路:

题目分析:
- 这道题要求设计一个数据结构,支持在平均时间复杂度为 O(1)的情况下执行插入、删除和获取随机元素的操作。
- 数据结构需要满足允许出现重复元素的条件。
- 插入操作需要在集合中插入元素,并返回一个布尔值表示集合是否不包含该元素。
- 删除操作需要从集合中移除一个指定的元素,并返回一个布尔值表示是否成功删除。
- 获取随机元素的操作需要从现有集合中随机获取一个元素,并且每个元素被返回的概率应该与其在集合中的数量呈线性相关。

主要思路:
- 使用一个哈希表'map'来存储元素和对应的出现次数。
- 使用一个数组'list'来存储元素。
- 插入操作时,将元素添加到数组中,并在哈希表中更新元素的出现次数。
- 删除操作时,从数组中移除元素,并在哈希表中更新元素的出现次数。
- 获取随机元素时,从数组中随机选择一个元素,并根据哈希表中元素的出现次数计算其被返回的概率。

以下是修改后的代码实现:

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

class RandomizedCollection {
    // 存储元素和对应的出现次数
    private Map<Integer, Integer> map;
    // 存储元素
    private List<Integer> list;
    // 随机数生成器
    private Random random;

    /** Initialize your data structure here. */
    public RandomizedCollection() {
        map = new HashMap<>();
        list = new ArrayList<>();
        random = new Random();
    }

    /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
    public boolean insert(int val) {
        boolean contains = map.containsKey(val);
        map.put(val, map.getOrDefault(val, 0) + 1);
        list.add(val);
        return!contains;
    }

    /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    public boolean remove(int val) {
        if (!map.containsKey(val)) {
            return false;
        }
        int count = map.get(val);
        map.put(val, count - 1);
        list.remove(Integer.valueOf(val));
        return count > 1;
    }

    /** Get a random element from the collection. */
    public int getRandom() {
        int randomIndex = random.nextInt(list.size());
        int randomElement = list.get(randomIndex);
        int count = map.get(randomElement);
        return randomElement;
    }

    // 测试用例
    public static void main(String[] args) {
        RandomizedCollection collection = new RandomizedCollection();
        System.out.println(collection.insert(1));
        System.out.println(collection.insert(1));
        System.out.println(collection.insert(2));
        System.out.println(collection.getRandom());
        System.out.println(collection.remove(1));
        System.out.println(collection.getRandom());
    }
}

在上述代码中,我们定义了一个'RandomizedCollection'类来实现数据结构。

- 'map'用于存储元素和对应的出现次数。
- 'list'用于存储元素。
- 'random'用于生成随机数。

插入操作:
- 首先检查元素是否已经存在于'map'中。
- 如果不存在,将元素添加到'map'中,并将其出现次数设置为 1。
- 将元素添加到'list'中。

删除操作:
- 首先检查元素是否存在于'map'中。
- 如果不存在,直接返回 false。
- 获取元素的出现次数。
- 将元素的出现次数减 1。
- 如果出现次数大于 1,直接返回 true。
- 如果出现次数等于 1,从'map'中移除元素,并从`list`中移除元素。

获取随机元素操作:
- 生成一个随机索引'randomIndex',范围是 0 到'list'的大小减 1。
- 获取随机索引对应的元素'randomElement'。
- 获取元素的出现次数'count'。
- 返回随机元素。

在'main'方法中,我们创建了一个'RandomizedCollection'对象,并进行了插入、删除和获取随机元素的操作。
(文章为作者在学习java过程中的一些个人体会总结和借鉴,如有不当、错误的地方,请各位大佬批评指正,定当努力改正,如有侵权请联系作者删帖。)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值