LeetCode 周赛 332,在套路里摸爬滚打~

news2024/11/20 11:45:45

本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。

大家好,今天是 3T 选手小彭。

上周是 LeetCode 第 332 场周赛,你参加了吗?算法解题思维需要长时间锻炼,加入我们一起刷题吧~


小彭的 Android 交流群 02 群已经建立啦,公众号回复 “加群” 加入我们~


2562.  找出数组的串联值(Easy)

题目地址

https://leetcode.cn/problems/find-the-array-concatenation-value/

题目描述

给你一个下标从  0  开始的整数数组  nums 。

现定义两个数字的  串联  是由这两个数值串联起来形成的新数字。

  • 例如,15  和  49  的串联是  1549 。

nums  的  串联值  最初等于  0 。执行下述操作直到  nums  变为空:

  • 如果  nums  中存在不止一个数字,分别选中  nums  中的第一个元素和最后一个元素,将二者串联得到的值加到  nums  的  串联值  上,然后从  nums  中删除第一个和最后一个元素。
  • 如果仅存在一个元素,则将该元素的值加到  nums  的串联值上,然后删除这个元素。

返回执行完所有操作后  nums  的串联值。

题解

简单模拟题,使用双指针向中间逼近即可。


class Solution {
    fun findTheArrayConcVal(nums: IntArray): Long {
        var left = 0
        var right = nums.size - 1
        var result = 0L
        while (left <= right) {
            result += if (left == right) {
                 nums[left]
            } else{
                Integer.valueOf("${nums[left]}${nums[right]}")
            }
            left++
            right--
        }
        return result
    }
}

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

2563.  统计公平数对的数目(Medium)

题目地址

https://leetcode.cn/problems/count-the-number-of-fair-pairs/

题目描述

给你一个下标从  0  开始、长度为  n  的整数数组  nums ,和两个整数  lower  和  upper ,返回  公平数对的数目 。

如果  (i, j)  数对满足以下情况,则认为它是一个  公平数对 :

  • 0 <= i < j < n,且
  • lower <= nums[i] + nums[j] <= upper

题解一(排序 + 枚举组合)

题目要求寻找 2 个目标数 nums[i]nums[j] 满足两数之和处于区间 [lower, upper] 。虽然题目强调了下标 i 和下标 j 满足 0 <= i < j < n,但事实上两个数的顺序并不重要,我们选择 nums[2] + nums[4] 与选择 nums[4] + nums[2] 的结果是相同的。因此,第一反应可以使用 “朴素组合模板”,时间复杂度是 O ( n 2 ) O(n^2) O(n2),但在这道题中会超出时间限制。

// 组合模板
class Solution {
    fun countFairPairs(nums: IntArray, lower: Int, upper: Int): Long {
        val n = nums.size
        var result = 0L
        for (i in 0 until nums.size - 1) {
            for (j in i + 1 until nums.size) {
                val sum = nums[i] + nums[j]
                if (sum in lower..upper) result++
            }
        }
        return result
    }
}

以示例 1 来说,我们发现在外层循环选择 nums[i] = 4 的一趟循环中,当内层循环选择 [ 4 + 4 ] [4 + 4] [4+4] 组合不满足条件后,选择一个比 4 4 4 更大的 [ 4 + 5 ] [4 + 5] [4+5] 组合显得没有必要。从这里容易想到使用 “排序” 剪去不必要的组合方案:我们可以先对输入数据进行排序,当内层循环的 nums[j] 不再可能满足条件时提前终止内层循环:

class Solution {
    fun countFairPairs(nums: IntArray, lower: Int, upper: Int): Long {
        // 排序 + 枚举组合
        var result = 0L
        nums.sort()
        for (i in 0 until nums.size - 1) {
            for (j in i + 1 until nums.size) {
                val sum = nums[i] + nums[j]
                if (sum < lower) continue
                if (sum > upper) break
                result++
            }
        }
        return result
    }
}

复杂度分析:

  • 时间复杂度: O ( n l g n + n 2 ) O(nlgn + n^2) O(nlgn+n2) 快速排序 + 组合的时间,其中 O ( n 2 ) O(n^2) O(n2) 是一个比较松的上界。
  • 空间复杂度: O ( l g n ) O(lgn) O(lgn) 快速排序占用的递归栈空间。

题解二(排序 + 二分查找)

使用排序优化后依然无法满足题目要求,我们发现:内层循环并不需要线性扫描,我们可以使用 O ( l g n ) O(lgn) O(lgn) 二分查找寻找:

  • 第一个大于等于 min 的数
  • 最后一个小于等于 max 的数

再使用这 2 个边界数的下标相减,即可获得内层循环中的目标组合个数。

class Solution {
    fun countFairPairs(nums: IntArray, lower: Int, upper: Int): Long {
        // 排序 + 二分查找
        var result = 0L
        nums.sort()
        for (i in 0 until nums.size - 1) {
            // nums[i] + x >= lower
            // nums[i] + x <= upper
            // 目标数的范围:[lower - nums[i], upper - nums[i]]
            val min = lower - nums[i]
            val max = upper - nums[i]
            // 二分查找优化:寻找第一个大于等于 min 的数
            var left = i + 1
            var right = nums.size - 1
            while (left < right) {
                val mid = (left + right - 1) ushr 1
                if (nums[mid] < min) {
                    left = mid + 1
                } else {
                    right = mid
                }
            }
            val minIndex = if (nums[left] >= min) left else continue
            // 二分查找优化:寻找最后一个小于等于 max 的数
            left = minIndex
            right = nums.size - 1
            while (left < right) {
                val mid = (left + right + 1) ushr 1
                if (nums[mid] > max) {
                    right = mid - 1
                } else {
                    left = mid
                }
            }
            val maxIndex = if (nums[left] <= max) left else continue
            result += maxIndex - minIndex + 1
        }
        return result
    }
}

复杂度分析:

  • 时间复杂度: O ( n l g n + n l g n ) O(nlgn + nlgn) O(nlgn+nlgn) 快速排序 + 组合的时间,内层循环中每次二分查找的时间是 O ( l g n ) O(lgn) O(lgn)
  • 空间复杂度: O ( l g n ) O(lgn) O(lgn) 快速排序占用的递归栈空间。

2564.  子字符串异或查询(Medium)

题目地址

https://leetcode.cn/problems/substring-xor-queries/

题目描述

给你一个  二进制字符串 s  和一个整数数组  queries ,其中  queries[i] = [firsti, secondi] 。

对于第  i  个查询,找到  s  的  最短子字符串 ,它对应的  十进制值  val  与  firsti 按位异或  得到  secondi ,换言之,val ^ firsti == secondi 。

第  i  个查询的答案是子字符串  [lefti, righti]  的两个端点(下标从  0  开始),如果不存在这样的子字符串,则答案为  [-1, -1] 。如果有多个答案,请你选择  lefti  最小的一个。

请你返回一个数组  ans ,其中  ans[i] = [lefti, righti]  是第  i  个查询的答案。

子字符串  是一个字符串中一段连续非空的字符序列。

前置知识

记 ⊕ 为异或运算,异或运算满足以下性质:

  • 基本性质:x ⊕ y = 0
  • 交换律:x ⊕ y = y ⊕ x
  • 结合律:(x ⊕ y) ⊕ z = x ⊕ (y ⊕ z)
  • 自反律:x ⊕ y ⊕ y = x

题解一(滑动窗口)

题目要求字符串 s 的最短子字符串,使其满足其对应的数值 val ⊕ first = second,根据异或的自反律性质可知(等式两边同异或 first),题目等价于求满足 val = first ⊕ second 的最短子字符串。

容易想到的思路是:我们单独处理 queries 数组中的每个查询,并计算目标异或值 target = first ⊕ second,而目标字符串的长度一定与 target 的二进制数的长度相同。所以,我们先获取 target 的有效二进制长度 len,再使用长度为 len 的滑动窗口寻找目标子字符串。由于题目要求 [left 最小的方案,所以需要在每次寻找到答案后提前中断。

class Solution {
    fun substringXorQueries(s: String, queries: Array<IntArray>): Array<IntArray> {
        // 寻找等于目标值的子字符串
        // 滑动窗口
        val n = s.length
        val result = Array(queries.size) { intArrayOf(-1, -1) }
        for ((index, query) in queries.withIndex()) {
            val target = query[0] xor query[1]
            // 计算 target 的二进制长度
            var len = 1
            var num = target
            while (num >= 2) {
                num = num ushr 1
                len++
            }
            for (left in 0..n - len) {
                val right = left + len - 1
                if (s.substring(left, right + 1).toInt(2) == target) {
                    result[index][0] = left
                    result[index][1] = right
                    break
                }
            }
        }
        return result
    }
}

复杂度分析:

  • 时间复杂度: O ( m n ) O(mn) O(mn),其中 m 是 queries 数组的长度,n 是字符串的长度,在这道题中会超时。
  • 空间复杂度: O ( 1 ) O(1) O(1),不考虑结果数组。

题解二(滑动窗口 + 分桶预处理)

事实上,如果每次都单独处理 queries 数组中的每个查询,那么题目将查询设置为数组就没有意义了,而且在遇到目标异或值 target 的二进制长度 len 相同时,会存在大量重复计算。因此,容易想到的思路是:我们可以预先将 queries 数组中所有二进制长度 len 相同的查询划分为一组,使相同长度的滑动窗口只会计算一次。

另一个细节是题目的测试用例中存在相同的查询,所以我们需要在映射表中使用 LinkedList 记录相同目标异或值 target 到查询下标 index 的关系。

class Solution {
    fun substringXorQueries(s: String, queries: Array<IntArray>): Array<IntArray> {
        // 寻找等于目标值的子字符串
        // 根据长度分桶:len to <target,index>
        val lenMap = HashMap<Int, HashMap<Int, LinkedList<Int>>>()
        for ((index, query) in queries.withIndex()) {
            val target = query[0] xor query[1]
            // 计算 target 的二进制长度
            var len = 1
            var num = target
            while (num >= 2) {
                num = num ushr 1
                len++
            }
            lenMap.getOrPut(len) { HashMap<Int, LinkedList<Int>>() }.getOrPut(target) { LinkedList<Int>() }.add(index)
        }
        // 滑动窗口
        val n = s.length
        val result = Array(queries.size) { intArrayOf(-1, -1) }
        for ((len, map) in lenMap) {
            for (left in 0..n - len) {
                val right = left + len - 1
                val curValue = s.substring(left, right + 1).toInt(2)
                if (map.containsKey(curValue)) {
                    for (index in map[curValue]!!) {
                        result[index][0] = left
                        result[index][1] = right
                    }
                    map.remove(curValue)
										// 该长度搜索结束
                    if (map.isEmpty()) break
                }
            }
        }
        return result
    }
}

复杂度分析:

  • 时间复杂度: O ( m + L n ) O(m + Ln) O(m+Ln),其中 n 是字符串的长度, m 是 queries 数组的长度,L 是不同长度的窗口个数, O ( m ) O(m) O(m) 是预处理的时间。根据题目输入满足 1 0 9 < 2 30 10^9 < 2^{30} 109<230 可知 L 的最大值是 30。
  • 空间复杂度: O ( m ) O(m) O(m),散列表总共需要记录 m 个查询的映射关系。

题解三(滑动窗口 + 预处理字符串)

这道题的思路也是通过预处理过滤相同长度的滑动窗口,区别在于预处理的是输入字符串,我们直接计算字符串 s 中所有可能出现的数字以及对应的 [left,right] 下标,再利用这份数据给予 queries 数组进行 O ( 1 ) O(1) O(1) 打表查询。

class Solution {
    fun substringXorQueries(s: String, queries: Array<IntArray>): Array<IntArray> {
        val n = s.length
        // 预处理
        val valueMap = HashMap<Int, IntArray>()
        for (len in 1..Math.min(n,31)) {
            for (left in 0..n - len) {
                val right = left + len - 1
                val num = s.substring(left, right + 1).toInt(2)
                if (!valueMap.containsKey(num)) {
                    valueMap[num] = intArrayOf(left, right)
                }
            }
        }
        val result = Array(queries.size) { intArrayOf(-1, -1) }
        for ((index, query) in queries.withIndex()) {
            val target = query[0] xor query[1]
            if (valueMap.containsKey(target)) {
                result[index] = valueMap[target]!!
            }
        }
        return result
    }
}

复杂度分析:

  • 时间复杂度: O ( L n + m ) O(Ln + m) O(Ln+m),其中 n 是字符串的长度, m 是 queries 数组的长度,L 是不同长度的窗口个数。 O ( L n ) O(Ln) O(Ln) 是预处理的时间,根据题目输入满足 1 0 9 < 2 30 10^9 < 2^{30} 109<230 可知 L 的最大值是 30。
  • 空间复杂度: O ( n L ) O(nL) O(nL),散列表总共需要记录 nL 个数的映射关系。

2565.  最少得分子序列(Hard)

题目地址

https://leetcode.cn/problems/subsequence-with-the-minimum-score/

题目描述

给你两个字符串  s  和  t 。

你可以从字符串  t  中删除任意数目的字符。

如果没有从字符串  t  中删除字符,那么得分为  0 ,否则:

  • 令  left  为删除字符中的最小下标。
  • 令  right  为删除字符中的最大下标。

字符串的得分为  right - left + 1 。

请你返回使  t  成为  s  子序列的最小得分。

一个字符串的  子序列  是从原字符串中删除一些字符后(也可以一个也不删除),剩余字符不改变顺序得到的字符串。(比方说  "ace"  是  "acde"  的子序列,但是  "aec"  不是)。

题解(前后缀分解)

这道题第一感觉是 LCS 最长公共子序列的衍生问题,我们可以使用朴素 LCS 模板求解字符串 s 和字符串 t 的最长公共子序列 ,再使用 t 字符串的长度减去公共部分长度得到需要删除的字符个数。

然而,这道题目的输出得分取决于最左边被删除的字符下标 i n d e x l e f t index_{left} indexleft 和最右边被删除字符的下标 i n d e x r i g h t index_{right} indexright,常规套路显得无从下手。所以,我们尝试对原问题进行转换:

  • 思考 1: 假设删除 leftright 两个字符后能够满足条件,那么删除 [left,right] 中间所有字符也同样能满足条件(贪心思路:删除更多字符后成为子序列的可能性更大);
  • 思考 1 结论: 原问题等价于求删除字符串 t 中的最短字符串 [i,j],使得剩余部分 [0, i - 1][j + 1, end] 合并后成为字符串 s 的一个子序列。
  • 思考 2: 如果字符串 t 删除 [i, j] 区间的字符后能够满足条件,那么一定存在剩余部分 [0, i - 1] 与字符串 s 的前缀匹配,而 [j + 1, end] 与字符串 s 的后缀匹配,而且这两段匹配的区域一定 “不存在” 交集。
  • 思考 2 结论: 我们可以枚举字符串 s 中的所有分割点,分别位于分割点的 s 前缀匹配 t 的前缀,用 s 的后缀匹配 t 的后缀,计算匹配后需要减去的子串长度,将所有枚举方案的解取最小值就是原题目的解。

思路参考视频讲解:https://www.bilibili.com/video/BV1GY411i7RP/ —— 灵茶山艾府 著

class Solution {
    fun minimumScore(s: String, t: String): Int {
        // 前后缀分解
        val n = s.length
        val m = t.length
        // s 的后缀和 t 的后缀匹配的最长子串的起始下标
        val sub = IntArray(n + 1).apply {
            var right = m - 1
            for (index in n - 1 downTo 0) {
                if (right >= 0 && s[index] == t[right]) right--
                this[index] = right + 1
            }
            this[n] = m
        }
        // s 的前缀和 t 的前缀匹配的最长子串的终止下标
        val pre = IntArray(n).apply {
            var left = 0
            for (index in 0..n - 1) {
                if (left < m && s[index] == t[left]) left++
                this[index] = left - 1
            }
        }
        // 枚举分割点
        var result = sub[0]
        if (0 == result) return 0 // 整个 t 是 s 的子序列
        for (index in 0 until n) {
            result = Math.min(result, m - (m - sub[index + 1]) - (pre[index] + 1))
        }
        return result
    }
}

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n),其中 n 是字符串 s 的长度,预处理和枚举的时间复杂度都是 O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n),前后缀数组的空间。

我们下周见,有用请赞赏上榜!想看小彭的更多题解代码,可关注 Github:https://github.com/pengxurui/LeetCode-Kotlin/tree/main/leetcode

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/352372.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023,再转行去做软件测试还有前途吗?

近年来&#xff0c;以云计算、移动互联网、物联网、工业互联网、人工智能、大数据及区块链等新一代信息技术构建的智能化应用和产品出现爆发式增长&#xff0c;突破了传统对于软件形态的认知&#xff0c;软件形态正以各种展现方式诠释着对新型智能软件的定义。这也使得软件的质…

Java提供了哪些IO方式? NIO如何实现多路复用?

第11讲 | Java提供了哪些IO方式&#xff1f; NIO如何实现多路复用&#xff1f; IO 一直是软件开发中的核心部分之一&#xff0c;伴随着海量数据增长和分布式系统的发展&#xff0c;IO 扩展能力愈发重要。幸运的是&#xff0c;Java 平台 IO 机制经过不断完善&#xff0c;虽然在某…

项目管理工具dhtmlxGantt甘特图入门教程(十):服务器端数据集成(上)

这篇文章给大家讲解如何利用dhtmlxGantt在服务器端集成数据。 dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表&#xff0c;可满足应用程序的所有需求&#xff0c;是完善的甘特图图表库 DhtmlxGantt正版试用下载&#xff08;qun&#xff1a;764148812&#…

考前梳理:PMP®备考之敏捷实践中的五大事件

今天为大家总结了PMP敏捷实践中的五大事件&#xff0c;帮助大家回顾考试重点&#xff0c;大家可以看着下方敏捷实践流程图进行个人构思&#xff0c;后文也会为大家一一剖析其中的重要环节。完整的Scrum敏捷实践框架流程图&#xff1a;一、冲刺计划会议 Sprint Planning1.为即将…

SQP求解器推导与matlab命令(JacobianHessian矩阵)

缩写&#xff1a; SQP(Sequential Quadratic Programming)序列二次规划 NLP 非线性规划问题 matlab代码 matlab中求解器 SQP的认识 《最优化方法及其Matlab程序设计》 书 马昌凤 SQP 知乎 基础知识点 I.Jacobian矩阵 Def: 一阶偏导 II.Hessian矩阵 Def: 二阶偏导 图 三阶…

【SpringCloud+Vue】生成微信二维码及扫码登录--OAuth2

OAuth2 微信登录流程 前端代码实现 后端代码实现 导入依赖 yml 实体类以及返回结果 工具类 微信配置信息 HTTP客户端连接池 JWT 控制层 业务层 持久层 OAuth2 OAuth2是OAuth&#xff08;Open Authorization&#xff0c;开放授权&#xff09;协议的延续版本。用来授…

Hinge Loss 和 Zero-One Loss

文章目录Hinge Loss 和 Zero-One LossHinge LossZero-One LossHinge Loss 和 Zero-One Loss 维基百科&#xff1a;https://en.wikipedia.org/wiki/Hinge_loss 图表说明&#xff1a; 纵轴表示固定 t1t1t1 的 Hinge loss&#xff08;蓝色&#xff09;和 Zero-One Loss&#xff…

字节5年测试经验,12月无情被辞,划水的兄弟别再这样了····

前言 先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入字节&#xff0c;以“人员优化”的名义无情被裁员&#xff0c;之后跳槽到了有赞&#xff0c;一直从事软件测试的工作。之前没有实习经历&#xff0c;算是5年的工作经验吧。 这5年之间完成…

实现一个小程序分享图 wxml2canvas

我们经常会遇上动态生成海报的需求&#xff0c;而在小程序中&#xff0c;生成图片非Canvas莫属。但是在实际工作当中&#xff0c;为了追求效率&#xff0c;我们会不可避免地去使用一些JS插件&#xff0c;而 wxml-to-canvas 就是一款官方推荐且非常优秀的插件&#xff0c;它可以…

图文详解Ansible中的变量及加密

文章目录一、变量命名二、变量级别三、.变量设定和使用方式1.在playbook中直接定义变量2.在文件中定义变量3.使用变量4.设定主机变量和清单变量5.目录设定变量6.用命令覆盖变量7.使用数组设定变量8.注册变量9.事实变量10.魔法变量四、JINJA2模板五、 Ansible的加密控制练习1.用…

I2C总线应用测试程序

参考链接&#xff1a;I2c协议 Linux I2C应用编程开发 问题背景 在工作中需要测试I2C总线的传输稳定性&#xff0c;需写一个测试程序通过读写从设备寄存器的值来验证数据传输稳定性。 站在cpu的角度来看&#xff0c;操作I2C外设实际上就是通过控制cpu中挂载该I2C外设的I2C控制…

yunUI组件库解析:图片上传与排序组件yImgPro

yunUI是笔者开源的微信小程序功能库。目前其中包含了一些复杂的功能组件。方便使用。未来它将分为组件、样式、js三者合为一体&#xff0c;但分别提供。 本文所用代码皆来源于组件库中的yImgPro组件。详细代码可至github查看。地址&#xff1a; yunUI 。 npm地址&#xff1a;yu…

Bing+ChatGPT 对传统搜索引擎的降维打击

早些时候申请了新版 Bing 的内测资格&#xff0c;终于收到了通过的邮件。 一天的体验之后&#xff0c;我的感受是&#xff1a;当新版 Bing 具备了 ChatGPT 的聊天能力之后&#xff0c;它的能力不论是对传统搜索引擎&#xff0c;还是 ChatGPT 自身&#xff0c;都将是降维打击。 …

LeetCode 237. 删除链表中的节点

原题链接 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 有一个单链表的 headheadhead&#xff0c;我们想删除它其中的一个节点 nodenodenode。 给你一个需要删除的节点 nodenodenode 。你将 无法访问 第一个节点 headheadhead。 链表的所有值都是 唯一的&…

IoT 边缘集群基于 Kubernetes Events 的告警通知实现(二):进一步配置

上一篇文章 IoT 边缘集群基于 Kubernetes Events 的告警通知实现 目标 告警恢复通知 - 经过评估无法实现原因: 告警和恢复是单独完全不相关的事件, 告警是 Warning 级别, 恢复是 Normal 级别, 要开启恢复, 就会导致所有 Normal Events 都会被发送, 这个数量是很恐怖的; 而且…

【重排重绘】从输入url到浏览器展示页面发生了什么?

目录步骤如下&#xff1a;一、用户在浏览器搜索栏中输入url地址二、浏览器解析域名得到服务器ip地址浏览器解析域名得到服务器ip地址有哪些过程&#xff1f;三、TCP三次握手建立客户端和服务器的连接四、客户端发送HTTP请求获取服务器端的静态资源五、服务器发送HTTP响应报文给…

程序员深度体验一周ChatGPT发现竟然....

程序员深度体验一周ChatGPT发现竟然… 周一打卡上班&#xff0c;老板凑到我跟前&#xff1a;“小李啊&#xff0c;这周有个新需求交给你做一下&#xff0c;给我们的API管理平台新增一个智能Mock的功能…”。我条件反射般的差点脱口而出&#xff1a;“这个需求做不了…”。不过…

【软件测试】资深测试总结的几个自动化测试点,提升跨越一大步......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 自动化的软件测试与…

PostgreSQL查询引擎——SELECT STATEMENTS SelectStmt

SelectStmt: select_no_parens %prec UMINUS| select_with_parens %prec UMINUS select_with_parens:( select_no_parens ) { $$ $2; }| ( select_with_parens ) { $$ $2; } 该规则返回单个SelectStmt节点或它们的树&#xff0c;表示集合操作树(set-operation tree…

JAVA线程池的使用

一、池化思想和JAVA线程池 池化是很重要的思想&#xff1b;池化的好处是提供缓冲和统一的管理。这个笔者在本人的数据库连接池的博客中已经提到过了&#xff08;JAVA常用数据库连接池_王者之路001的博客-CSDN博客 &#xff09;。 线程池是另一种池化思想的运用&#xff0c;把…