LeetCode 周赛 340,质数 / 前缀和 / 极大化最小值 / 最短路 / 平衡二叉树

今天讲 LeetCode 单周赛第 340 场,今天状态不好,掉了一波大分。

2614. 对角线上的质数(Easy)

这道题是最近第 2 次出现质数问题,注意 1 不是质数!

  • 质数判断:$O(n·\sqrt(U))$

2615. 等值距离和(Medium)

这道题是标准的前缀和数组题目,我们有从暴力到前缀和的解法,最后有消除前缀和数组的最优解法,理解从暴力解法到最优解法的推导过程非常重要。

  • 题解 1:暴力 $O(n^2)$
  • 题解 2:前缀和数组 $O(n) + O(n)$
  • 题解 3:前缀和 + DP $O(n) + O(1)$

2616. 最小化数对的最大差值(Medium)

这道题是 “极大化最小值” 问题,与以前我们讲过的 “高楼丢鸡蛋” 问题属于同一种类型,理解 “极大化最小值” 中的单调性与二分查找的思路非常重要。

  • 贪心 + 二分查找 $O(nlgn + nlgU)$

2617. 网格图中最少访问的格子数(Hard)

这道题是经典题目 45. 跳跃游戏 II 的二维版本,我创新性地从图的最短路视角理解 跳跃游戏 II,再迁移到这道二维数组问题上,难度降低为 Medium。

  • 最短路 BFS + 平衡二叉树 + 队列 $O(nm·(lgn + lgm))$


2614. 对角线上的质数(Easy)

题目地址

力扣

题目描述

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

返回位于 nums 至少一条 对角线 上的最大 质数 。如果任一对角线上均不存在质数,返回 0 。

注意:

  • 如果某个整数大于 1 ,且不存在除 1 和自身之外的正整数因子,则认为该整数是一个质数。
  • 如果存在整数 i ,使得 nums[i][i] = val 或者 nums[i][nums.length - i - 1]= val ,则认为整数 val 位于 nums 的一条对角线上。

题解(质数)

遍历两条对角线上的元素,如果是质数则更新答案。注意 1 不是质数!

另外再检查数据量,数组的长度 n 最大为 300,而数据最大值为 4*10^6,所以用朴素的质数判断算法能满足要求。

class Solution {
    fun diagonalPrime(nums: Array<IntArray>): Int {
        var ret = 0
        val n = nums.size
        for (i in 0 until n) {
            val num1 = nums[i][i]
            val num2 = nums[i][n - 1 - i]
            if (num1 > ret && isPrime(num1)) ret = num1
            if (num2 > ret && isPrime(num2)) ret = num2
        }
        return ret
    }

    private fun isPrime(num: Int): Boolean {
        if (num == 1) return false
        var x = 2
        while (x * x <= num) {
            if (num % x == 0) {
                return false
            }
            x++
        }
        return true
    }
}

复杂度分析:

  • 时间复杂度:$O(n·\sqrt(U))$ 其中 n 是 nums 二维数组的长度,U 是输入数据的最大值;
  • 空间复杂度:$O(1)$ 仅使用常量级别空间。

近期周赛质数问题:

  • 2600. 质数减法运算(Medium)

2615. 等值距离和(Medium)

题目地址

力扣

题目描述

给你一个下标从 0 开始的整数数组 nums 。现有一个长度等于 nums.length 的数组 arr 。对于满足 nums[j] == nums[i] 且 j != i 的所有 j ,arr[i] 等于所有 |i - j| 之和。如果不存在这样的 j ,则令 arr[i] 等于 0 。

返回数组 **arr 

问题分析

容易想到,不同数值之间互不影响,所以先对数组元素分组,再依次计算组内元素之间的距离差绝对值之和。

题解一(暴力 · 超出时间限制)

暴力解法是计算每个位置与其他组内元素的距离差绝对值。

class Solution {
    fun distance(nums: IntArray): LongArray {
        val n = nums.size
        // 分组
        val map = HashMap<Int, ArrayList<Int>>()
        for (index in nums.indices) {
            map.getOrPut(nums[index]) { ArrayList<Int>() }.add(index)
        }
        val ret = LongArray(n)
        // 暴力
        for ((_, indexs) in map) {
            for (i in indexs.indices) {
                for (j in indexs.indices) {
                    ret[indexs[i]] += 0L + Math.abs(indexs[i] - indexs[j])
                }
            }
        }
        return ret
    }
}

复杂度分析:

  • 时间复杂度:$O(n^2)$ 其中 n 为 nums 数组的长度
  • 空间复杂度:$O(1)$ 不考虑分组的数据空间。

题解二(前缀和数组)

分析计算元素 x 与组内元素距离差绝对值之和的过程:

以组内下标为 [0, 1, 2, 3, 4, 5] 为例,下标 [2] 位置的距离和计算过程为:

  • (x - 0) + (x - 1) + (x - x) + (3 - x) + (4 - x) + (5 - x)

我们以 [2] 为分割点将数组分为两部分,则发现:

  • (x - 0) - (x - 1) 正好等于 (左边元素个数 * x) - 左边元素之和
  • (3 - x) + (4 - x) + (5 - x) 正好等于 (右边元素之和) - (右边元素个数 * x)

数组区间和有前缀和的套路做法,可以以空间换时间降低时间复杂度。

  • 细节:x * i 是 Int 运算会溢出,需要乘以 1 转换为 Long 运算
class Solution {
    fun distance(nums: IntArray): LongArray {
        val n = nums.size
        // 分组
        val map = HashMap<Int, ArrayList<Int>>()
        for (index in nums.indices) {
            map.getOrPut(nums[index]) { ArrayList<Int>() }.add(index)
        }
        val ret = LongArray(n)
        // 分组计算
        for ((_, indexs) in map) {
            val m = indexs.size
            // 前缀和
            val preSums = LongArray(m + 1)
            for (i in indexs.indices) {
                preSums[i + 1] = preSums[i] + indexs[i]
            }
            for ((i, x) in indexs.withIndex()) {
                // x * i 是 Int 运算会溢出,需要乘以 1 转换为 Long 运算
                val left = 1L * x * i - preSums[i]
                val right = (preSums[m] - preSums[i + 1]) - 1L * x * (m - 1 - i)
                ret[x] = left + right
            }
        }
        return ret
    }
}

复杂度分析:

  • 时间复杂度:$O(n)$ 其中 n 为 nums 数组的长度,分组、前缀和的时间是 $O(n)$,每个位置的距离和计算时间为 $O(1)$;
  • 空间复杂度:$O(n)$ 不考虑分组空间,需要前缀和数组 $O(n)$。

题解三(前缀和 + DP)

将 left + right 的计算公式合并,则有

ret[x] = x * i - preSums[i] + (preSums[m] - preSums[i + 1]) - x * (m - 1 - i)

化简得:

ret[x] = (preSums[m] - preSums[i + 1]) - preSums[i] + x (2 * i - m + 1)

发现可以直接维护元素左右两边的元素之和,省去前缀和数据空间。

class Solution {
    fun distance(nums: IntArray): LongArray {
        val n = nums.size
        // 分组
        val map = HashMap<Int, ArrayList<Int>>()
        for (index in nums.indices) {
            map.getOrPut(nums[index]) { ArrayList<Int>() }.add(index)
        }
        val ret = LongArray(n)
        // 前缀和 DP
        for ((_, indexs) in map) {
            val m = indexs.size
            var leftSum = 0L
            var rightSum = 0L
            for (element in indexs) {
                rightSum += element
            }
            for ((i, x) in indexs.withIndex()) {
                rightSum -= x
                ret[x] = rightSum - leftSum + 1L * x * (2 * i - m + 1)
                leftSum += x
            }
        }
        return ret
    }
}

复杂度分析:

  • 时间复杂度:$O(n)$ 其中 n 为 nums 数组的长度,分组时间是 $O(n)$,每个位置的距离和计算时间为 $O(1)$;
  • 空间复杂度:$O(1)$ 不考虑分组空间。

相似题目:

  • 1685. 有序数组中差绝对值之和

2616. 最小化数对的最大差值(Medium)

题目地址

力扣

题目描述

给你一个下标从 0 开始的整数数组 nums 和一个整数 p 。请你从 nums 中找到 p 个下标对,每个下标对对应数值取差值,你需要使得这 p 个差值的 最大值 最小。同时,你需要确保每个下标在这 p 个下标对中最多出现一次。

对于一个下标对 i 和 j ,这一对的差值为 |nums[i] - nums[j]| ,其中 |x| 表示 x 的 绝对值 。

请你返回 p 个下标对对应数值 最大差值 的 最小值 。

问题分析

二分思路:“极大化最小值” 和 “极小化最小值” 存在单调性,是典型的二分查找问题。

  • 二分的值越大,越能 / 越不能满足条件;
  • 二分的值越小,越不能 / 越能满足条件。

贪心思路:由于元素位置不影响结果,可以先排序,尽量选相邻元素。

题解(二分 + 贪心)

如何二分?

  • 二分的 left:0,无法构造出更小的差值;
  • 二分的 right:数组的最大值 - 数组的最小值,无法构造出更大的差值;
  • 我们可以选择一个差值 max,再检查差值 max 是否能够构造出来:
    • 如果存在差值为 max 的方案:那么小于 max 的差值都不能构造(无法构造出更小的差值);
    • 如果不存在差值为 max 的方案:那么大于 max 的差值都能构造(任意调整数对使得差值变大即可);

如何判断 “差值为 max 的方案”,即 “存在至少 p 个数对,它们的最大差值为 max 的方案” 存在?

这里需要思维转换,由于我们希望差值尽可能小,所谓我们不需要真的去构造差值为 max 的方案,而是尽可能构造出差值不超过 max 的方案,只要差值不超过 max 的方案数大于等于 p 个,那么至少有不高于 max 的差值方案存在。

举个例子,在数列 [1, 1, 2, 3, 7, 10] 中,p = 2,检查的差值 max = 5。此时我们构造数列对 {1, 1} {2, 3} 满足差值不超过 max 且方案数大于等于 p 个,那么 max 就是可构造的,且存在比 max 更优的方案。

所以,现在的问题转换为如何构造出尽可能多的数列数,使得它们的差值不超过 max?

如果当前元素 x 参与配对,那么配对相邻数的差值是最小的,否则 x 与不相邻数匹配无法得到更优解。

class Solution {
    fun minimizeMax(nums: IntArray, p: Int): Int {
        if (p == 0) return 0
        // 排序
        nums.sort()
        val n = nums.size
        // 二分查找
        var left = 0
        var right = nums[n - 1] - nums[0]
        while (left < right) {
            val mid = (left + right) ushr 1
            if (check(nums, p, mid)) {
                right = mid
            } else {
                left = mid + 1
            }
        }
        return left
    }

    // 检查
    private fun check(nums: IntArray, p: Int, max: Int): Boolean {
        var cnt = 0
        var i = 0
        while (i < nums.size - 1) {
            if (nums[i + 1] - nums[i] <= max) {
                // 选
                i += 2
                cnt += 1
            } else {
                i += 1
            }
            if (cnt == p) return true
        }
        return false
    }
}

复杂度分析:

  • 时间复杂度:$O(nlgn + nlgU)$ 其中 n 是 nums 数组的长度,U 是数组的最大差值。预排序时间为 $O(nlgn)$,二分次数为 $lgU$,每轮检查时间为 $O(n)$;
  • 空间复杂度:$O(lgn)$ 排序递归栈空间。

2617. 网格图中最少访问的格子数(Hard)

题目地址

力扣

题目描述

给你一个下标从 0 开始的 m x n 整数矩阵 grid 。你一开始的位置在 左上角 格子 (0, 0) 。

当你在格子 (i, j) 的时候,你可以移动到以下格子之一:

  • 满足 j < k <= grid[i][j] + j 的格子 (i, k) (向右移动),或者
  • 满足 i < k <= grid[i][j] + i 的格子 (k, j) (向下移动)。

请你返回到达 右下角 格子 (m - 1, n - 1) 需要经过的最少移动格子数,如果无法到达右下角格子,请你返回 -1 。

问题分析

分析 1 - 题意:这道题的题意可能有点小绕,其实就是说站在 [i][j] 位置上,且 grid[i][j] = x,则最远可以走到向右 [i][j + x] 或向下 [i + x][j] 的位置上。现在求从左上角到右下角的最少移动次数,显然,这是一个在二维空间上的最短路问题,将格子之间的可达关系视为图的边,也可以视为图上的最短路问题。

初看之下这道题与经典题 45. 跳跃游戏 II 非常相似,简直是二维上的跳跃游戏问题。在 45. 这道题中,有时间复杂度 O(n) 且空间复杂度 O(1) 的动态规划解法,我也可以用图的思路去思考 45. 题(当然它的复杂度不会由于动态规划)

45. 跳跃游戏 II(最短路思路)

定义 dst[i] 表示到达 i 位置的最少跳跃次数,那么对于 i 位置可以到达的区间 (i+1, i + nums[i]),它们的最少跳跃次数最多不会高于 dst[i] + 1。

参考 Dijkstra 最短路算法的思路,我们将数组分为 “已确定集合” 和 “候选集合” 两组,那么对于已确定集合中最短路长度最小的节点 j,由于该点不存在更优解,所以可以用该点来确定其它店的最短路长度。

而且由于这道题中图的边权是 1,所以只要越早进入 “已确定集合” 中的点的最短路长度越低,不需要使用小顶堆来搜索 “已确定集合中最短路长度最小的节点”

class Solution {
    fun jump(nums: IntArray): Int {
        val n = nums.size
        val INF = Integer.MAX_VALUE
        // 候选集
        val unVisitSet = HashSet<Int>(n).apply {
            // 排除 0
            for (i in 1 until n) {
                this.add(i)
            }
        }
        // 最短路长度
        val dst = IntArray(n) { INF }
        dst[0] = 0
        // 队列
        val queue = LinkedList<Int>()
        queue.offer(0)
        while (!queue.isEmpty()) {
            // 由于边权为 1,队列中最先访问的节点一定是最短路长度最短的节点
            val from = queue.poll()
            // 更新可达范围
            for (to in from + 1..Math.min(from + nums[from], n - 1)) {
                if (!unVisitSet.contains(to)) continue
                // 最短路
                queue.offer(to)
                dst[to] = dst[from] + 1
                // 从候选集移除
                unVisitSet.remove(to)
                // 到达终点
                if (to == n - 1) break
            }
        }
        return dst[n - 1]
    }
}

复杂度分析:

  • 时间复杂度:$O(n^2)$ 其中 n 是 nums 数组的长度,每个节点最多入队一次,每次出队最多需要扫描 n - 1 个节点
  • 空间复杂度:$O(n)$

在内层循环更新可达范围时,会重复检查已经确定最短路长度的点,我们可以使用平衡二叉树优化,这就类似于上一场周赛中第 4 题 2612. 最少翻转操作数 的思路。

class Solution {
    fun jump(nums: IntArray): Int {
        val n = nums.size
        val INF = Integer.MAX_VALUE
        // 候选集(平衡二叉树)
        val unVisitSet = TreeSet<Int>().apply {
            // 排除 0
            for (i in 1 until n) {
                this.add(i)
            }
        }
        // 最短路长度
        val dst = IntArray(n) { INF }
        dst[0] = 0
        // 队列
        val queue = LinkedList<Int>()
        queue.offer(0)
        while (!queue.isEmpty()) {
            // 由于边权为 1,队列中最先访问的节点一定是最短路长度最短的节点
            val from = queue.poll()
            // 更新可达范围
            val max = Math.min(from + nums[from], n - 1)
            while (true) {
                // 大于等于 from 的第一个元素
                val to = unVisitSet.ceiling(from) ?: break
                if (to > max) break
                // 最短路
                queue.offer(to)
                dst[to] = dst[from] + 1
                // 从候选集移除
                unVisitSet.remove(to)
                // 到达终点
                if (to == n - 1) break
            }
        }
        return dst[n - 1]
    }
}

复杂度分析:

  • 时间复杂度:$O(nlgn)$ 其中 n 是 nums 数组的长度,每个节点最多入队一次,每次寻找左边界的时间是 O(lgn);
  • 空间复杂度:$O(n)$ 平衡二叉树空间。

题解(BFS + 平衡二叉树 + 队列)

理解了用最短路思路解决一维数组上的跳跃游戏 II,很容易推广到二维数组上:

  • 1、由于题目每个位置有向右和向下两个选项,所以我们需要建立 m + n 个平衡二叉树;
  • 2、由于存在向右和向下两种可能性
class Solution {
    fun minimumVisitedCells(grid: Array<IntArray>): Int {
        val n = grid.size
        val m = grid[0].size
        if (n == 1 && m == 1) return 1
        // 每一列的平衡二叉树
        val rowSets = Array(n) { TreeSet<Int>() }
        val columnSets = Array(m) { TreeSet<Int>() }
        for (row in 0 until n) {
            for (column in 0 until m) {
                if (row + column == 0) continue
                rowSets[row].add(column)
                columnSets[column].add(row)
            }
        }
        // 队列(行、列、最短路长度)
        val queue = LinkedList<IntArray>()
        queue.offer(intArrayOf(0, 0, 1))

        while (!queue.isEmpty()) {
            val node = queue.poll()
            val row = node[0]
            val column = node[1]
            val dst = node[2]
            val step = grid[row][column]

            // 向右
            var max = Math.min(column + step, m - 1)
            while (true) {
                val to = rowSets[row].ceiling(column) ?: break
                if (to > max) break
                // 最短路
                queue.offer(intArrayOf(row, to, dst + 1))
                // 从候选集移除(行列都需要移除)
                rowSets[row].remove(to)
                columnSets[column].remove(row)
                // 到达终点
                if (row == n - 1 && to == m - 1) return dst + 1
            }

            // 向下
            max = Math.min(row + step, n - 1)
            while (true) {
                val to = columnSets[column].ceiling(row) ?: break
                if (to > max) break
                // 最短路
                queue.offer(intArrayOf(to, column, dst + 1))
                // 从候选集移除(行列都需要移除)
                rowSets[row].remove(row)
                columnSets[column].remove(to)
                // 到达终点
                if (to == n - 1 && column == m - 1) return dst + 1
            }
        }
        return -1
    }
}

复杂度分析:

  • 时间复杂度:$O(nm·(lgn + lgm))$ 其中 n 是行数,m 是列数,每个点最多入队一次,每次出队需要 O(lgn + lgm) 时间确定左边界;
  • 空间复杂度:$O(nm)$ 平衡二叉树空间。 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小程序裂变怎么做?小程序裂变机制有哪些?

做了小程序就等于“生意上门”&#xff1f;其实并不是这样。小程序跟流量平台较为明显的区别就在于小程序并非“自带流量”&#xff0c;而是需要企业利用自己的营销推广能力来建立引流渠道&#xff0c;从而完成用户的拉新和留存、转化。因此&#xff0c;想要用小程序来增加自己…

直线电机模组在激光切割机上的作用

激光切割机是将从激光器发射出的激光&#xff0c;经光路系统&#xff0c;聚焦成高功率密度的激光束。激光束照射到工件表面&#xff0c;使工件达到熔点或沸点&#xff0c;同时与光束同轴的高压气体将熔化或气化金属吹走。激光切割加工是用不可见的光束代替了传统的机械刀&#…

【2.3】Java微服务:sentinel服务哨兵

✅作者简介&#xff1a;大家好&#xff0c;我是 Meteors., 向往着更加简洁高效的代码写法与编程方式&#xff0c;持续分享Java技术内容。 &#x1f34e;个人主页&#xff1a;Meteors.的博客 &#x1f49e;当前专栏&#xff1a;Java微服务 ✨特色专栏&#xff1a; 知识分享 &…

24v转3.3v输出3A用什么芯片

问&#xff1a;客户需要一个能够将24V输入电压转换为3.3V输出电压&#xff0c;并且能够提供1-3A的电流输出的芯片。还希望它能够内置MOS管。有什么推荐的型号吗&#xff1f;&#xff08;vin24v、5v&#xff0c;vout3.3v&#xff0c;Io1-3A&#xff09; 答&#xff1a;推荐使用…

Python程序设计基础:函数(一)

文章目录 一、函数的基本概念二、函数的定义和使用1、函数的定义与调用2、函数的参数3、返回多个值 一、函数的基本概念 在使用Python实现某些复杂的功能的时候&#xff0c;容易遇到一些重复率较高的代码&#xff0c;为了代码能够重复使用并提升代码的整洁度&#xff0c;函数这…

aardio + customPlus 显示图片演示

看效果&#xff1a; 上代码&#xff1a; import win.ui; /*DSG{{*/ var winform win.form(text"aardio customPlus 显示图片演示 by 光庆";right927;bottom607) winform.add( button{cls"button";text"下一页";left664;top536;right794;bott…

支持多用户协同的思维导图TeamMapper

什么是 TeamMapper &#xff1f; TeamMapper 是基于 Mindmapp 开发的用于绘制思维导图的 Web 应用程序。它使得思维导图变得简单&#xff0c;你可以托管并创建您自己的思维导图。与您的团队分享您的思维导图会议并在思维导图上进行协作。 软件特点&#xff1a; 创建&#xff1…

详细教程:如何搭建废品回收小程序

废品回收是一项环保举措&#xff0c;通过回收和再利用废弃物品&#xff0c;可以减少资源浪费和环境污染。近年来&#xff0c;随着智能手机的普及&#xff0c;小程序成为了推广和运营的重要工具。本文将详细介绍如何搭建一个废品回收小程序。 1. 进入乔拓云网后台 首先&#xf…

微服务架构基础--第3章Spring Boot核心功能讲解

第3章Spring Boot核心功能讲解 一.预习笔记 1.使用maven创建SpringBoot项目 1-1:创建一个maven项目 1-2:在pom文件中导入依赖 1-3&#xff1a;编写启动类&#xff08;注意启动类的位置&#xff09; 1-4&#xff1a;编写测试类 1-5&#xff1a;运行SpringBoot启动类 2.了解p…

成功解决Android设备adb连接后显示device unauthorized

一、提出问题 在电脑通过USB连接新的Android设备&#xff0c;想要通过adb来进行一些操作时&#xff0c;却发现命令提示符上在输入下面命令后显示设备未授权的信息也就是"unauthorized" adb devices二、不可行的解决方案 有人提出的解决方案是打开Android设备的开发…

分布式协议与算法——CAP理论、ACID理论、BASE理论

CAP理论 CAP理论&#xff0c;对分布式系统的特性做了高度抽象&#xff0c;比如抽象成了一致性、可用性和分区容错性&#xff0c;并对特性间的冲突&#xff08;也就是CAP不可能三角&#xff09;做了总结。 CAP三指标 CAP理论对分布式系统的特性做了高度抽象&#xff0c;形成了…

解决layui框架的radio属性不显示失效问题

废话不多说 直接开干&#xff01; 1.问题描述使用layui时 2.不显示问题 纠结半天 忘记插件要刷新 步骤 3、解决方法就是&#xff1a;使用form.render() 刷新请求的界面 <script type"text/javascript">//刷新界面 所有元素layui.use(form,function(){var form …

SQL SERVER ip地址改别名

SQL server在使用链接服务器时必须使用别名&#xff0c;使用ip地址就会把192.188.0.2这种点也解析出来 解决方案&#xff1a; 1、物理机ip 192.168.0.66 虚拟机ip 192.168.0.115 2、在虚拟机上找到 C:\Windows\System32\drivers\etc 下的 &#xff08;我选中的文件&a…

网络安全渗透测试之靶场训练

NWES: 7月26号武汉地震检测中心遭受境外具有政府背景的黑客组织和不法分子的网络攻击。 目前网络攻击主要来自以下几种方式: DDOS&#xff1a;分布式拒绝服务攻击。通过制造大量无用的请求向目标服务器发起访问&#xff0c;使其因短时间内无法处理大量请求而陷入瘫痪。主要针对…

Elasticsearch 商业启示

上月的“红帽事件”&#xff0c;说明开源软件的“客服模式”行不通&#xff0c;那么&#xff0c;开源软件如何赚钱呢&#xff1f;既不能卖软件&#xff0c;又不能卖支持服务&#xff0c;该怎么办呢&#xff1f;我现在的看法是&#xff0c;只剩下一种模式是可行的&#xff0c;开…

【多音音频测试信号】具有指定采样率和样本数的多音信号,生成多音信号的相位降低波峰因数研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Jtti:Ubuntu静态IP地址怎么配置

在 Ubuntu 中配置静态 IP 地址需要编辑网络配置文件。以下是在 Ubuntu 20.04 版本中配置静态 IP 地址的步骤&#xff1a; 打开终端&#xff0c;以管理员身份登录或使用 sudo 权限。 使用以下命令打开网络配置文件进行编辑&#xff1a; sudo nano /etc/netplan/00-installer-…

webpack基础知识五:说说Loader和Plugin的区别?编写Loader,Plugin的思路?

一、区别 前面两节我们有提到Loader与Plugin对应的概念&#xff0c;先来回顾下 loader 是文件加载器&#xff0c;能够加载资源文件&#xff0c;并对这些文件进行一些处理&#xff0c;诸如编译、压缩等&#xff0c;最终一起打包到指定的文件中plugin 赋予了 webpack 各种灵活的…

【计算机网络】网络层协议 -- ICMP协议

文章目录 1. ICMP协议简介2. ICMP协议格式3. ping命令4. ping命令与端口号没有关系&#xff01;&#xff01;&#xff01;5. traceroute命令 1. ICMP协议简介 ICMP&#xff08;Internet Control Message Protocol&#xff0c;控制报文协议&#xff09;&#xff0c;用于在IP主机…

实时通信应用的开发:Vue.js、Spring Boot 和 WebSocket 整合实践

目录 1. 什么是webSocket 2. webSocket可以用来做什么? 3. webSocket协议 4. 服务器端 5. 客户端 6. 测试通讯 1. 什么是webSocket WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务…
最新文章