你一个实习生你抢什么红包?

7d29e95b95b41a1e0e47cf7aa6516aca.gif

精品推荐

《征服数据结构》专栏:50多种数据结构彻底征服

《经典图论算法》专栏:50多种经典图论算法全部掌握

一实习的网友因为在公司群里抢了一个红包,被领导问:你一个实习的抢什么?我还以为是多大红包呢,总共就发200块钱,这格局……,怪不得网友评论说:今天我抢你红包,明天我抢你风头,后天我抢你老婆,大后天我还抢你位置。。。

f59fe6c0c14d3a34a2990b9474fe27fb.png

bea32c055d78ed17ead728d75287fd66.png

在给大家来一道智力测试题:

A blind man is alone on a deserted island. He has two blue pills and two red pills. He must take exactly one red pill and one blue pill or he will die.  

How does he do it?

翻译过来就是:

一个盲人独自一人待在一个荒岛上。他有两粒蓝色药丸和两粒红色药丸。他必须服用一粒红色药丸和一粒蓝色药丸,否则他就会死。

他应该怎么做?一小时之后评论区见答案。

--------------下面是今天的算法题--------------

来看下今天的算法题,这题是LeetCode的第220题:存在重复元素 III。

问题描述

来源:LeetCode第220题

难度:困难

给你一个整数数组 nums 和两个整数 indexDiff 和 valueDiff 。找出满足下述条件的下标对 (i, j):

1,i != j

2,abs(i - j) <= indexDiff

3,abs(nums[i] - nums[j]) <= valueDiff

如果存在,返回 true ;否则,返回 false 。

示例1:

输入:nums = [1,2,3,1], indexDiff = 3, valueDiff = 0

输出:true

解释:可以找出 (i, j) = (0, 3) 。

满足下述 3 个条件:

i != j --> 0 != 3

abs(i - j) <= indexDiff --> abs(0 - 3) <= 3

abs(nums[i] - nums[j]) <= valueDiff --> abs(1 - 1) <= 0

示例2:

输入:nums = [1,5,9,1,5,9], indexDiff = 2, valueDiff = 3

输出:false

解释:尝试所有可能的下标对 (i, j) ,均无法满足这 3 个条件,因此返回 false 。

  • 2 <= nums.length <= 10^5

  • -10^9 <= nums[i] <= 10^9

  • 1 <= indexDiff <= nums.length

  • 0 <= valueDiff <= 10^9

问题分析

这题是存在重复元素的第 3 题,前面两道题都比较简单,具体可以看下:

《存在重复元素》

《存在重复元素 II》

这题要求的是在数组中找出两个元素,它们的下标差与值的差都小于给定的值。这题也是一道滑动窗口问题,窗口的大小是indexDiff+1,这样我们就可以保证在窗口中的任何两个元素的下标差都不会大于indexDiff。

然后我们在窗口中找出与当前元素差值最小的元素,判断它俩的差值是否小于等于valueDiff。

为了方便查找,我们使用TreeSet作为窗口,每次查找和当前元素最接近的,一个比它大的一个比它小的值。

JAVA:

public boolean containsNearbyAlmostDuplicate(int[] nums, int indexDiff, int valueDiff) {
    TreeSet<Integer> set = new TreeSet<>();
    for (int i = 0; i < nums.length; i++) {
        int num = nums[i];
        // 查找集合中小于或者等于num的最大值
        Integer floor = set.floor(num);
        // 查找集合中大于或者等于num的最小值
        Integer ceiling = set.ceiling(num);
        // 如果查找到任何一个,他们的值相差小于等于valueDiff,直接返回true
        if ((floor != null && num - floor <= valueDiff) ||
                (ceiling != null && ceiling - num <= valueDiff)) {
            return true;
        }
        // 否则把当前元素加入到集合set中
        set.add(num);
        if (i >= indexDiff) {
            // 把最前面的给移除,因为最前面的元素和当前元素的下标
            // 大于indexDiff了,即使他们的差小于等于valueDiff,
            // 也不会满足条件
            set.remove(nums[i - indexDiff]);
        }
    }
    return false;
}

684163cd2580d2a0708f8c668d473f7e.gif

笔者简介

博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解800多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。

《征服数据结构》专栏

数组稀疏表(Sparse Table)单向链表双向链表块状链表跳表队列和循环队列双端队列单调队列单调栈双端栈散列表字典树(Trie树)ArrayMapSparseArray二叉树二叉搜索树(BST)笛卡尔树AVL树树堆(Treap)FHQ-Treap

……

《经典图论算法》专栏

图的介绍图的表示方式邻接矩阵转换广度优先搜索(BFS)深度优先搜索(DFS)A*搜索算法迭代深化深度优先搜索(IDDFS)IDA*算法双向广度优先搜索迪杰斯特拉算法(Dijkstra)贝尔曼-福特算法(Bellman-Ford)SPFA算法弗洛伊德算法(Floyd)

……

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

数据结构和算法

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值