自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(35)
  • 收藏
  • 关注

原创 力扣-hot100(搜索二维矩阵)

二分查找,题目强调有序数据,天然的符合二分条件,常规的二分就是取中间点, 然后观察这个点的值与目标值比较是大了还是小了。而这里二维二分,基本思路一样,初始取整个数组的中间坐标,根据得到的点不断更新 x,y 即可。输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5。每列的所有元素从上到下升序排列。每行的元素从左到右升序排列。每列的元素从上到下升序排列。

2025-05-07 14:04:18 382

原创 力扣-hot100(旋转图像)

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]输出:[[7,4,1],[8,5,2],[9,6,3]]旋转图像,这意味着你需要直接修改输入的二维矩阵。请你将图像顺时针旋转 90 度。// 再按对角线翻转。使用另一个矩阵来旋转图像。

2025-05-07 13:50:27 462

原创 力扣-hot100(螺旋矩阵)

模拟: 第一个周期:行的第一行,列的倒数第一列,行的倒数第一行,列的第一列;第二个周期:行的第二行,列的倒数第二列,行的倒数第二行,列的第二列.....输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]输出:[1,2,3,4,8,12,11,10,9,5,6,7]// 从右到左遍历底部行。// 从下到上遍历左侧列。// 从左到右遍历顶部行。输出:[1,2,3,6,9,8,7,4,5]

2025-05-07 13:47:37 790

原创 力扣-hot100 (矩阵置零)

/ 为了不破坏原来的结构, 就是被感染成 0 的不能再去感染别的数, 只有初始为0的数才能去感染其它数。// 可进行优化, 因为这里只要把行和列的下标索引记录下来就可以了。输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]输出:[[1,0,1],[0,0,0],[1,0,1]]的矩阵,如果一个元素为。

2025-05-06 17:14:54 2136

原创 力扣-hot100 (缺失的第一个正数)

这里将每个遍历到的值都将数组的索引做一个标记 (为了不影响这个数本身的价值,将其标为负数, 用到该数时再取绝对值, 但如果这里原来数组的数本来就是负数呢?这里是要找缺失的第一个正数,负数是没有价值的, 所以我们可以将初始就为负数的数替换为一个特定的数. 为了不影响结果, 这个特定的数是要保证是存在的, 所以我们可以将其替换为 1 ~ n+1 的任何数, 只要在预处理的时候检查他存在, 但题目要求的是需要第一个正数, 故如果选择后面的数会出现漏掉前面较小的数的检查. 所以最小数1是你的不二选择)。

2025-05-06 16:51:18 1114

原创 力扣hot100 (除自身以外数组的乘积)

常规做法是可以开两个数组left[nums.size]、right[nums.size]记录.但仔细观察后可以发现这里每个元素的左右侧乘积是连续的. 也就是第i个元素的左乘积 = 第 i - 1 元素的左乘积 * 第 i - 1个元素, 可使用一个变量记录上一个元素的左乘积得到. 同理可以计算右乘积。// 第i个元素的左乘积 = 第 i - 1 元素的左乘积 * 第 i - 1 个元素。输入: nums = [-1,1,0,-3,3] 输出: [0,0,9,0,0]// 先将所有元素的左乘积给计算出来。

2025-05-05 20:37:26 642

原创 力扣hot100 (轮转数组)

输入: nums = [1,2,3,4,5,6,7], k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: [5,6,7,1,2,3,4]输入:nums = [-1,-100,3,99], k = 2 输出:[3,99,-1,-100] 解释: 向右轮转 1 步: [99,-1,-100,3] 向右轮转 2 步: [3,99,-1,-100]// 计算第i个元素存放的位置。

2025-05-05 19:47:36 312

原创 力扣hot100 - 合并区间

如果小于则 可以进行区间合并 进行第 i - 1 的右区间进行更新 否则开一个加入一个新的区间。输入:intervals = [[1,4],[4,5]] 输出:[[1,5]] 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。// 如果新加入队列的元素 <= 当前队列中的最后一个元素 -> 则可以进行合并。// 更新其右端点后加入到队列中, 更新的值应该是两个区间右端点的最大值。// 不能合并的情况, 直接将新的元素加入队列中。// 拿到队列中最后一个元素。执行用时分布 7ms 击败 88.71%

2025-05-05 19:15:22 463

原创 力扣-hot100(和为k的子数组)

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数。输入:nums = [1,2,3], k = 3 输出:2。子数组是数组中元素的连续非空序列。

2025-04-25 11:23:25 236

原创 力扣-hot100(找到字符串中的所有字母异位词)

输入: s = "cbaebabacd", p = "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。解法一:暴力统计,每次取出s的p.length()个字符从头到位遍历,然后进行排序,观察是否和p排序后一样。438. 找到字符串中所有字母异位词。

2025-04-25 11:22:18 270

原创 力扣-hot100(滑动窗口最大值)

里面的数据如:13、11、9、5、1、0。// 公司还有员工的情况下,发现了一个新加入的员工,他不仅年轻(靠后),能力还更强(数更大), 那就从kpi低的老员工开始优化。// 如果员工的数量已经可以评出优秀员工了,就选出第一名(其实就是第 i == k - 1 后开始的, 因为i的下标从0开始)输入:nums = [1,3,-1,-3,5,3,6,7], k = 3 输出:[3,3,5,5,6,7] 解释: 滑动窗口的位置 最大值。// 观察了新员工的简历,先把能力比新员工低的老员工优化了(也就是后面的)

2025-04-25 11:19:51 939

原创 力扣-hot100(无重复字符的最长子串)

维护一个队列,每次往队列中加入元素,就去看看队列中是否有一个相同的元素已经在里面了,如果有,就把元素从前往后进行结算,再将该元素加入队列中,以此类推,得到最长子串.解法二: 用Set来维护这些元素(set.contains(c)的时间复杂度为O(1)),那怎么保留队列的性质呢?我们只需要在加入元素的时候一直加加加,加到厌倦(出现了重复元素),然后移除的时候只需要移除掉那个重复元素就行。// 除了第一次加入元素外,其它都是上一轮加到重复了才会停止,所以将上一个字符移除。// 判断队列中是否存在这么一个元素。

2025-04-19 19:53:54 936

原创 力扣-hot100(接雨水-双指针)

思路:双指针分别指向两侧,不断向中间靠近,如果靠近的过程中右边最长的柱子长度 大于 左边最长的柱子长度,短板效应,那么就可以计算左边当前的空穴可以装多少水了【是由左边最长的柱子和左边当前柱子的长度差决定的(leftMax - height[left])】输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

2025-04-19 11:21:55 377

原创 力扣-hot100(三数之和-双指针)

/ 去重:只对能组成三元组的去重, 这里不能出现重复的三元组,如果类似于nums[l] 和nums[l + 1] 是相同的话,那就是确定了两个数(nums[i] 和 nums[l]都确定了),第三数也会被随之确定下来。不同的三元组是 [-1,0,1] 和 [-1,-1,2]。输入:nums = [-1,0,1,2,-1,-4]输出:[[-1,-1,2],[-1,0,1]]注意,输出的顺序和三元组的顺序并不重要。输入:nums = [0,1,1]输入:nums = [0,0,0]输出:[[0,0,0]]

2025-04-16 14:27:29 802

原创 力扣-hot100(盛最多水的容器-双指针)

补充: 这样做会不会漏掉,这里漏掉的情况只可能有一种,就是当两个高相等时,移动了随机一根,但是要明确的是高的长度是由最短的那根确定下来的,即便你后面有很长的,也会被这两根相同的限制,所以不论移动哪根都是一样的。解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。容器的长是由两直线(宽)的距离决定的,容器的高是两直线中最短的那根确定的。实事上并不是每条边(高)都是有价值的,宽的价值是很好确定的,最两侧的边,为宽的最大权重。// 容器的长是由两直线的距离决定的,容器的高是两直线中最短的那根。

2025-04-16 13:56:25 947

原创 力扣-hot100(移动零-双指针)

/right不断往后扩展找到不为0的数与前面的数交换,与哪个位置的数交换呢?,上述代码是找到不为0的数往前移动,然后在最后补零。依据题目可以看到是要把某个固定的元素给往后移动,既然如此,我们就可以把那个固定的元素保存下来,再把其它元素往前移动,然后最后的n个固定元素可以直接补齐。// right为快指针,目的是找到不为0的数,将其往左移动,left负责记录下不为0的数的个数。移动到数组的末尾,同时保持非零元素的相对顺序。输入: nums = [0,1,0,3,12]输出: [1,3,12,0,0]

2025-04-16 13:39:00 377

原创 力扣-hot100(最长连续序列 - Hash)

那么我可以将数组中的分为 n 个组,毕竟组是相对有序的,比直接在乱七八糟的原数组里直接做要来的方便。一旦断了,那断的那个数你就自己做队长去招募你的队员吧。我们只需要从队长开始不断的报数就可以统计该组的元素数量,然后求每个组的max就行了。第一想法,先预处理一波,可以创建一个数组把存在的数都标记一遍,如:nums = [100,4,200],标记:number[100] = 1, number[4] = 1, number[200] = 1;,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

2025-04-15 16:04:02 723

原创 力扣 - Hot100 (字母异位词分组 - Hash)

题目要求按异位词来分组,也就是只要组成单词的字母完全相同,就可以被称为一个组,他们就应该有同样的唯一性标识可以进入同一个组,也就是要有同样的key。而题目中的成员是String类型,这就很容易了,让每个String排个序,同一组的异位词不就可以等到同样的结果吗。有没有这样一种数据结构可以维护n个不同的组,并且能检测每个想加入的成员的唯一性标识来决定给你分配到哪个组 (不然每个元素都可以加入任意组那我分组的意义在哪?// 加入失败,您加入的组不存在。// 维护n个组,每个组互为字母异位词。

2025-04-14 21:09:03 1748

原创 苍穹外卖day04

webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));System.out.println("收到来自客户端:" + sid + "的信息:" + message);System.out.println("客户端:" + sid + "建立连接");System.out.println("连接断开:" + sid);

2025-04-14 20:24:17 843

原创 苍穹外卖day03

用户请求-> 后端服务器 -> 微信官方的服务器 -> 后端服务器(得到响应,老用户就用微信官方返回的结构和查询本地数据库的数据进行对比,新用户就插入数据到本地) -> 响应给用户登录状态。// 设置key序列化方式。业务为基本增删改查,注意的是在做增删改查的时候首先要考虑好本次数据操作涉及哪几个表,理清整条线的逻辑,再进行业务开发。// 订单详情表为补充订单信息,部分数据是从购物车中获取的,所以需要查询购物车数据。// 订单表是主表,部分数据是从地址表中获取的,所以需要先查询地址数据。

2025-04-13 20:39:52 480

原创 苍穹外卖day02

与前面接口相比学到的有:1、引用了第三方工具阿里云OSS进行图片文件缓存;2、同一接口进行多个表查询and维护代码原子性;(数据关性。

2025-04-13 14:38:20 476

原创 力扣-hot100(两数之和 - Hash)

优化,想法:如果这是一个有序的数组那么就,只需要用双指针指向两边逐渐向中间靠拢,则遍历n次就可保证得到。答:这里的核心在于,对于数组中的每个元素 num,需要快速判断数组里是否存在另一个元素 target - num,并且要知道它们各自的索引。:有没有一个结构能将前面遍历过的数都存储起来,往后遍历时只需要用目标值减去当前遍历到的值,然后判断之前是否有存储过这么一个值(有的 兄弟有的)。解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]。整数,并返回它们的数组下标。

2025-04-13 13:28:50 894

原创 Redis实现签到功能

Bitmap使用Redis数据结构实现完成,如01010 就表示这个月(月分以key的形式存储)第2、4天签到了:SetBit(指定位置存入0|1)、getBit(获取指定位置的bit,下标从0开始)BitCount(统计BitMap中值为1的数量)、Bitpos(第一个0|1出现的位置)Bitfield(获取bit数组,以10进制形式返回)、Bitfield_ro、Bitop、// 签到实现@Override// 1.获取当前登录用户// 2.获取日期。

2025-04-11 19:22:51 550

原创 Redis实现附件店铺

RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs().includeDistance().limit(end) //这里是从第一条到结束,所以要截取需要的数据返回。new Distance(5000),//距离圆心的距离。// 3.查询redis、按照距离排序、分页。// 2.把店铺分组,按照typeId分组,typeId一致的放到一个集合。// 不需要坐标查询,按数据库查询。// 3.2.获取同类型的店铺的集合。// 4.2.获取店铺id。

2025-04-11 19:21:46 708

原创 Redis实现数据推送

就是要实现有数据变动的分页查询,比如说,每次查询3个,刚开始查询到7,6,5后又插进来一个数8,那么按以往的分页查询page = page * page_size = 1 * 3 = 3 确定起始位置,下次查询从第4个开始查询,而新插进来一个数,此时的第四个就是旧数据的第三个。,当张三和李四发了消息后,都会保存在自己的邮箱中,假设赵六要读取信息,那么他会从读取他自己的收件箱,此时系统会从他关注的人群中,把他关注人的信息全部都进行拉取到自己的收件箱,然后在进行排序。时效快,不用临时拉取,数据冗余内存压力大。

2025-04-11 19:20:30 1726

原创 Redis实现点赞功能

ZSET问题:防重复点赞,通过 Redis 判断用户是否已点赞,避免重复操作。数据库和 Redis 协同维护点赞状态,确保前端展示一致性。利用 Redis 的原子操作(如 ZSET)快速处理点赞 / 取消点赞请求,减少数据库压力。基于 Redis 有序集合按时间戳排序,高效获取点赞排行榜。Redis数据结构:Redis 有序集合(ZSET),存储用户 ID 和点赞时间戳,保证唯一性( 天然去重);通过 快速判断用户是否已点赞;使用 获取点赞排行榜(如前 5 名);Redis命令:ZADD key sco

2025-04-11 19:19:11 946

原创 苍穹外卖Day01

使用PageHelper工具类开启分页查询,PageHelper会在执行sql前进行拦截并且拼接分页sql,然后进行查询时返回数据类型为Page<>,这样返回的该对象会包含总记录数、总页数、当前页码、每页记录数等分页信息。点击 “VCS”→“Git”→“Remotes”,点 “+”,“Name” 填 “origin”,“URL” 粘贴 Gitee 复制的地址,测试连接后确认。// 在 autoFillPointCut 所定义的切入点的目标方法执行前执行。// 获取到当前被拦截的方法上的数据库操作类型。

2025-04-11 14:57:46 460

原创 Redis实现消息队列

就是下单之后,利用redis去进行校验下单条件,再通过队列把消息存入消息队列中,然后再启动一个线程去消费这个消息,完成解耦,同时也加快我们的响应速度。使用 LPUSH 写入消息,RPOP/BRPOP 消费消息,实现生产者 - 消费者模型;采用发布订阅模型,支持多生产、多消费、不支持数据持久化、无法避免消息丢失、消息堆积有上限,超出时数据丢失。异步解耦:将下单请求快速写入消息队列,异步处理库存扣减和订单生成,避免阻塞主线程,提升系统响应速度;//为0,把下单信息保存到阻塞队列。// 获取代理对象(事务)

2025-04-05 13:18:45 804

原创 全局唯一ID

通过结合时间戳和序列号,利用 Redis 的原子性操作生成全局唯一 ID,确保在分布式环境下生成的 ID 是唯一的。:INCR icr:product:2025:04:04,INCR命令是 Redis 的原子性操作,它会将指定键的值加 1,如果键不存在,则会先将键的值初始化为 0 再进行加 1 操作。// 64位:1(符号位,永为0)、2-32(时间戳,以秒为单位)、33-64(序列号,秒内的计数器):借助 Redis 的原子性操作 INCR 来生成序列号,确保在分布式环境下序列号的唯一性和原子性。

2025-04-05 13:17:25 628

原创 Redis实现分布式锁

使用这把锁不使用主从,每个节点的地位都是一样的, 这把锁加锁的逻辑需要写入到每一个主丛节点上,只有所有的服务器都写入成功,此时才是加锁成功,假设现在某个节点挂了,那么他去获得锁的时候,只要有一个节点拿不到,都不能算是加锁成功,保证了加锁的可靠性。:用state变量来记录重入的状态的,比如当前没有人持有这把锁,那么state=0,假如来一个人持有这把锁,那么state++,释放一次就-1 ,直到减少成0 时,表示当前这把锁没有被人持有。假如他在一个方法内,调用另一个方法,那么此时如果是不可重入的,就死锁了)

2025-04-04 17:19:21 859

原创 Redis缓存查询

若先删缓存再写数据库,在这两个操作之间可能:又来了一个读请求触发 “缓存未命中(此时缓存被删除) → 查数据库(此时数据库更新操作还未完成) → 写入旧数据到缓存” 的流程,导致脏数据。//判断是否存在 Redis缓存中为null,直接返回null,因为热点key是会先做数据预热的,如果redis中没有则表名该key不是热点key。此时数据库中没有,redis中自然也没有缓存相应的资源,因此大量请求打到数据库中,给数据库带来巨大压力。//此时只存在两种情况:null(没有查询过,数据库中可能有);

2025-04-04 17:17:18 692

原创 Redis实现短信登录

发送验证码前端请求后校验手机号,生成 6 位随机验证码(如RandomUtil.randomNumbers(6))。将验证码存入 Redis(键格式login:code:手机号),设置 5 分钟有效期。javastringRedisTemplate.opsForValue().set("login:code:" + phone, code, 5, TimeUnit.MINUTES);验证验证码从 Redis 中获取缓存的验证码(键login:code:手机号),与用户输入的验证码比对。jav

2025-04-02 21:02:31 897

原创 Redis引用

Spring集成Redis前配置~

2025-03-30 20:52:39 263

原创 归并排序--分治思想

2、分界点选取mid, 需要开一个数组来记录 q[l..mid] , q[mid+1..r] 中从小到大排序的所有数。分治: 这个大区间被划分n次当只剩下一个数的时候, 显然这个子区间是有序的.合并两个只一个数的区间得到两个数的区间,显然也是有序的.我们在解决此问题只需要关注子问题的解决, 所有子问题解决完后再合并子问题.得到整个大问题的解决。解决子问题: 将分成的两个区间各用一个指针变量指向起始位置, 用arr记录两个区间排序结果。1、与快排类似, 不同的是归并排序是先分成若干子问题, 再解决子问题。

2024-10-24 20:13:29 311

原创 快速排序 || 快排

这个大区间被划分n次当只剩下一个数的时候, 显然这个子区间是有序的. 合并两个只一个数的区间得到两个数的区间,显然也是有序的.因为上面子问题解决保证了(右边的数 >= 左边) 左右两边的有序数会被分别划分为一个区间,之前的数是有序的得到的区间必然也是有序的. 以此类推得到的整个大区间自然也是有序的.选择一个参考值(可左|右|中间...), 再定义两个指针分别指向最左和最右,在指针没有相遇前使所有左边的数小于参考值, 右边的所有数大于参考值. 这样结束后得到两个排好序的子区间(右边的数 >= 左边)

2024-10-23 21:17:26 415

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除