剑指Offer题目笔记16(TreeSet和TreeMap的应用)

文章讲述了两道编程面试题:一是使用TreeSet判断整数数组中是否存在两个元素,其差的绝对值在给定范围内;二是使用TreeMap实现一个日程表,检查添加时间区域是否冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面试题57:

面试题57

问题:

​ 给定一个整数数组ums和两个正数k、t,请判断是否存在两个不同的下标和满足i和j之差的绝对值不大于给定的k,并且两个数值nums[i和nums[j]的差的绝对值不大于给定的t。

解决方案:

​ 使用TreeSet作为数据容器,因为需要从一个大小为k的数据容器中找出小于或等于某个数字的最大值及大于或等于某个数字的最小值,逐一扫描数组中的每个数字,对于每个nums[i]来说,应该先从它前面k个数字中找出小于或者等于nums[i]的最大的数字,如果该数字与nums[i]的差的绝对值不大于t,则返回true,反之返回false。否则,先从它前面k个数字中找出大于或者等于nums[i]的最小的数字,如果该数字与nums[i]的差的绝对值不大于t,则返回true,反之返回false。

源代码:
class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int indexDiff, int valueDiff) {
        TreeSet<Long> set = new TreeSet<>();

        for(int i = 0;i < nums.length;i++){
            Long lower = set.floor((long)nums[i]);
            if(lower != null && lower >= (long)nums[i] - valueDiff){
                return true;
            }

            Long upper = set.ceiling((long)nums[i]);
            if(upper != null && upper <= (long)nums[i] + valueDiff){
                return true;
            }

            set.add((long)nums[i]);
            if(i >= indexDiff){
                set.remove((long)nums[i-indexDiff]);
            }
        }

        return false;
    }
}

面试题58:

面试题58

问题:

​ 实现该类的book(int start, int end)在日程表中添加一个时间区域为[start,end)的事项(这是一个半开半闭区间)。

解决方案:

​ 使用TreeMap作为数据容器。将时间区域的开始时间作为映射的键,把结束时间作为映射的值。

源代码:
class MyCalendar {

    TreeMap<Integer,Integer> events;

    public MyCalendar() {
        events = new TreeMap<>();
    }
    
    public boolean book(int start, int end) {
        Map.Entry<Integer,Integer> event = events.floorEntry(start);
        if(event != null && event.getValue() > start){
            return false;
        }

        event = events.ceilingEntry(start);
        if(event != null && event.getKey() < end){
            return false;
        }

        events.put(start,end);
        return true;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值