力扣:42. 接雨水 84.柱状图中最大的矩形(单调栈,双指针)

news2024/9/25 19:23:44

这两道题解题思路类似,一个是单调递增栈,一个是单调递减栈。本篇博客给出暴力,双指针和单调栈解法。

42. 接雨水

题目:

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

在这里插入图片描述

示例 1:

输入:

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 个单位的雨水(蓝色部分表示雨水)。

示例 2:

输入:

height = [4,2,0,3,2,5]

输出:

9

提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

思路:

暴力解法:

本题暴力解法也是也是使用双指针。

首先要明确,要按照行来计算,还是按照列来计算。

按照行来计算如图:
在这里插入图片描述

按照列来计算如图:
在这里插入图片描述
按照列来计算,比较容易理解,接下来看一下按照列如何计算。

首先,如果按照列来计算的话,宽度一定是1了,我们再把每一列的雨水的高度求出来就可以了。

可以看出每一列雨水的高度,取决于该列左侧最高的柱子和右侧最高的柱子中最矮的那个柱子的高度。

这句话可以有点绕,来举一个理解,例如求列4的雨水高度,如图:
在这里插入图片描述
列4 左侧最高的柱子是列3,高度为2(以下用lHeight表示)。

列4 右侧最高的柱子是列7,高度为3(以下用rHeight表示)。

列4 柱子的高度为1(以下用height表示)

那么列4的雨水高度为 列3和列7的高度最小值减列4高度,即: min(lHeight, rHeight) - height。

列4的雨水高度求出来了,宽度为1,相乘就是列4的雨水体积了。

此时求出了列4的雨水体积。

一样的方法,只要从头遍历一遍所有的列,然后求出每一列雨水的体积,相加之后就是总雨水的体积了。

首先从头遍历所有的列,并且要注意第一个柱子和最后一个柱子不接雨水,代码如下:

class Solution:
    def trap(self, height: List[int]) -> int:
        res = 0  # 初始化结果变量
        for i in range(len(height)):
            if i == 0 or i == len(height)-1: continue  # 如果是第一个或最后一个元素,跳过
            lHight = height[i-1]  # 初始化左侧最高高度为前一个元素的高度
            rHight = height[i+1]  # 初始化右侧最高高度为后一个元素的高度
            for j in range(i-1):
                if height[j] > lHight:
                    lHight = height[j]  # 更新左侧最高高度
            for k in range(i+2,len(height)):
                if height[k] > rHight:
                    rHight = height[k]  # 更新右侧最高高度
            res1 = min(lHight,rHight) - height[i]  # 计算当前位置可以储水的高度
            if res1 > 0:
                res += res1  # 累加结果
        return res  # 返回最终结果

因为每次遍历列的时候,还要向两边寻找最高的列,所以时间复杂度为O(n^2),空间复杂度为O(1)。

力扣后面修改了后台测试数据,所以以上暴力解法超时了

双指针优化:

在暴力解法中,我们可以看到只要记录左边柱子的最高高度 和 右边柱子的最高高度,就可以计算当前位置的雨水面积,这就是通过列来计算。

当前列雨水面积:min(左边柱子的最高高度,记录右边柱子的最高高度) - 当前柱子高度。

为了得到两边的最高高度,使用了双指针来遍历,每到一个柱子都向两边遍历一遍,这其实是有重复计算的。我们把每一个位置的左边最高高度记录在一个数组上(maxLeft),右边最高高度记录在一个数组上(maxRight),这样就避免了重复计算。

当前位置,左边的最高高度是前一个位置的左边最高高度和本高度的最大值。

即从左向右遍历:maxLeft[i] = max(height[i], maxLeft[i - 1]);

从右向左遍历:maxRight[i] = max(height[i], maxRight[i + 1]);

代码如下:

class Solution:
    def trap(self, height: List[int]) -> int:
        res = 0  # 初始化结果变量为0
        max_left = [0] * len(height)  # 创建一个列表用于存储每个位置左侧的最大高度
        max_right = [0] * len(height)  # 创建一个列表用于存储每个位置右侧的最大高度
        max_left[0] = height[0]  # 初始化第一个位置的最大左侧高度为第一个位置的高度
        max_right[-1] = height[-1]  # 初始化最后一个位置的最大右侧高度为最后一个位置的高度
        # 计算每个位置左侧的最大高度
        for i in range(1, len(height)):
            max_left[i] = max(height[i], max_left[i - 1])
        # 计算每个位置右侧的最大高度
        for j in range(len(height) - 2, -1, -1):
            max_right[j] = max(height[j], max_right[j + 1])
        # 计算每个位置上的积水量,并累加到结果变量中
        for i in range(len(height)):
            rain = min(max_left[i], max_right[i]) - height[i]
            res += rain
        return res  # 返回最终的积水总量

单调栈解法:

单调栈就是保持栈内元素有序。和单调队列 一样,需要我们自己维持顺序,没有现成的容器可以用。

通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。

而接雨水这道题目,我们正需要寻找一个元素,右边最大元素以及左边最大元素,来计算雨水面积。

准备工作

那么本题使用单调栈有如下几个问题:

  1. 首先单调栈是按照行方向来计算雨水,如图:

在这里插入图片描述
知道这一点,后面的就可以理解了。

  1. 使用单调栈内元素的顺序

从大到小还是从小到大呢?

从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。

因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。

  1. 遇到相同高度的柱子怎么办。

遇到相同的元素,更新栈内下标,就是将栈里元素(旧下标)弹出,将新元素(新下标)加入栈中。

例如 5 5 1 3 这种情况。如果添加第二个5的时候就应该将第一个5的下标弹出,把第二个5添加到栈中。

因为我们要求宽度的时候 如果遇到相同高度的柱子,需要使用最右边的柱子来计算宽度。

如图:
在这里插入图片描述

  1. 栈里要保存什么数值

使用单调栈,也是通过 长 * 宽 来计算雨水面积的。

长就是通过柱子的高度来计算,宽是通过柱子之间的下标来计算,

那么栈里有没有必要存一个pair<int, int>类型的元素,保存柱子的高度和下标呢。

其实不用,栈里就存放下标就行,想要知道对应的高度,通过height[stack.top()] 就知道弹出的下标对应的高度了。

明确了如上几点,我们再来看处理逻辑。

单调栈处理逻辑

以下逻辑主要就是三种情况

  • 情况一:当前遍历的元素(柱子)高度小于栈顶元素的高度 height[i] < height[stack[-1]]
  • 情况二:当前遍历的元素(柱子)高度等于栈顶元素的高度 height[i] == height[stack[-1]]
  • 情况三:当前遍历的元素(柱子)高度大于栈顶元素的高度height[i] > height[stack[-1]]

先将下标0的柱子加入到栈中,stack = [0]。 栈中存放我们遍历过的元素,所以先将下标0加进来。

然后开始从下标1开始遍历所有的柱子,for i in range(1, len(height)):

如果当前遍历的元素(柱子)高度小于栈顶元素的高度,就把这个元素加入栈中,因为栈里本来就要保持从小到大的顺序(从栈头到栈底)。

代码如下:

            if height[i] < height[stack[-1]]:
                stack.append(i)

如果当前遍历的元素(柱子)高度等于栈顶元素的高度,要跟更新栈顶元素,因为遇到相相同高度的柱子,需要使用最右边的柱子来计算宽度。

代码如下

            elif height[i] == height[stack[-1]]:
                stack.pop
                stack.append(i)

如果当前遍历的元素(柱子)高度大于栈顶元素的高度,此时就出现凹槽了,如图所示:
在这里插入图片描述

取栈顶元素,将栈顶元素弹出,这个就是凹槽的底部,也就是中间位置,下标记为mid,对应的高度为height[mid](就是图中的高度1)。

此时的栈顶元素stack[-1],就是凹槽的左边位置,下标为stack[-1],对应的高度为height[stack[-1]](就是图中的高度2)。

当前遍历的元素i,就是凹槽右边的位置,下标为i,对应的高度为height[i](就是图中的高度3)。

此时大家应该可以发现其实就是栈顶和栈顶的下一个元素以及要入栈的元素,三个元素来接水!

那么雨水高度是 min(凹槽左边高度, 凹槽右边高度) - 凹槽底部高度,代码为:h = min(height[i], height[stack[-1]]) - height[mid]

雨水的宽度是 凹槽右边的下标 - 凹槽左边的下标 - 1(因为只求中间宽度),代码为:w = i - stack[-1] - 1

当前凹槽雨水的体积就是:h * w。

求当前凹槽雨水的体积代码如下:

                while stack and height[i] > height[stack[-1]]:
                    mid = stack[-1]
                    stack.pop()
                    if stack:
                        h = min(height[i], height[stack[-1]]) - height[mid]
                        w = i - stack[-1] - 1
                        res += h * w

代码及详细注释:

暴力法:

class Solution:
    def trap(self, height: List[int]) -> int:
        res = 0  # 初始化结果变量
        for i in range(len(height)):
            if i == 0 or i == len(height)-1: continue  # 如果是第一个或最后一个元素,跳过
            lHight = height[i-1]  # 初始化左侧最高高度为前一个元素的高度
            rHight = height[i+1]  # 初始化右侧最高高度为后一个元素的高度
            for j in range(i-1):
                if height[j] > lHight:
                    lHight = height[j]  # 更新左侧最高高度
            for k in range(i+2,len(height)):
                if height[k] > rHight:
                    rHight = height[k]  # 更新右侧最高高度
            res1 = min(lHight,rHight) - height[i]  # 计算当前位置可以储水的高度
            if res1 > 0:
                res += res1  # 累加结果
        return res  # 返回最终结果

双指针优化:

class Solution:
    def trap(self, height: List[int]) -> int:
        res = 0  # 初始化结果变量为0
        max_left = [0] * len(height)  # 创建一个列表用于存储每个位置左侧的最大高度
        max_right = [0] * len(height)  # 创建一个列表用于存储每个位置右侧的最大高度
        max_left[0] = height[0]  # 初始化第一个位置的最大左侧高度为第一个位置的高度
        max_right[-1] = height[-1]  # 初始化最后一个位置的最大右侧高度为最后一个位置的高度
        # 计算每个位置左侧的最大高度
        for i in range(1, len(height)):
            max_left[i] = max(height[i], max_left[i - 1])
        # 计算每个位置右侧的最大高度
        for j in range(len(height) - 2, -1, -1):
            max_right[j] = max(height[j], max_right[j + 1])
        # 计算每个位置上的积水量,并累加到结果变量中
        for i in range(len(height)):
            rain = min(max_left[i], max_right[i]) - height[i]
            res += rain
        return res  # 返回最终的积水总量

单调栈:

class Solution:
    def trap(self, height: List[int]) -> int:
        res = 0  # 初始化结果变量为0
        stack = [0]  # 创建一个栈,用于存储索引
        for i in range(1, len(height)):
            if height[i] < height[stack[-1]]:  # 如果当前高度小于栈顶所对应的高度
                stack.append(i)  # 将当前索引入栈
            elif height[i] == height[stack[-1]]:  # 如果当前高度等于栈顶所对应的高度
                stack.pop  # 弹出栈顶
                stack.append(i)  # 将当前索引入栈
            else:  # 如果当前高度大于栈顶所对应的高度
                while stack and height[i] > height[stack[-1]]:  # 当栈非空且当前高度大于栈顶所对应的高度
                    mid = stack[-1]  # 弹出栈顶,并将其作为中间高度
                    stack.pop()  # 弹出栈顶
                    if stack:  # 如果栈非空
                        h = min(height[i], height[stack[-1]]) - height[mid]  # 计算高度差
                        w = i - stack[-1] - 1  # 计算宽度
                        res += h * w  # 计算积水量并累加到结果变量中
                stack.append(i)  # 将当前索引入栈
        return res  # 返回最终的积水总量

84. 柱状图中最大的矩形

题目:

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:

在这里插入图片描述

输入:

heights = [2,1,5,6,2,3]

输出:

10

解释:

最大的矩形为图中红色区域,面积为 10

示例 2:

在这里插入图片描述

输入:

heights = [2,4]

输出:

4

提示:

  • 1 <= heights.length <=105
  • 0 <= heights[i] <= 104

思路:

暴力解法:

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        res = 0  # 初始化结果变量为0

        for i in range(len(heights)):  # 遍历数组
            left = i  # 初始化左指针为当前位置
            right = i  # 初始化右指针为当前位置
            for _ in range(left, -1, -1):  # 从左指针位置向左遍历
                if heights[left] < heights[i]:  # 如果左侧高度小于当前高度
                    break  # 退出循环
                left -= 1  # 左指针左移
            for _ in range(right, len(heights)):  # 从右指针位置向右遍历
                if heights[right] < heights[i]:  # 如果右侧高度小于当前高度
                    break  # 退出循环
                right += 1  # 右指针右移
                
            width = right - left - 1  # 计算宽度
            height = heights[i]  # 当前位置的高度
            res = max(res, width * height)  # 计算面积并更新结果变量

        return res  # 返回最大矩形面积

如上代码并不能通过leetcode,超时了,因为时间复杂度是 O ( n 2 ) O(n^2) O(n2)

双指针解法:

本题双指针的写法整体思路和42. 接雨水 (opens new window)是一致的,但要比42. 接雨水 (opens new window)难一些。

难就难在本题要记录记录每个柱子 左边第一个小于该柱子的下标,而不是左边第一个小于该柱子的高度。

所以需要循环查找,也就是下面在寻找的过程中使用了while循环

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        size = len(heights)  # 获取数组长度
        min_left_index = [0] * size  # 初始化存储左边界的数组
        min_right_index = [0] * size  # 初始化存储右边界的数组
        result = 0  # 初始化结果变量为0

        min_left_index[0] = -1  # 第一个元素的左边界为-1
        for i in range(1, size):  # 遍历数组,计算每个位置的左边界
            temp = i - 1
            while temp >= 0 and heights[temp] >= heights[i]:  # 寻找左边第一个小于当前高度的位置
                temp = min_left_index[temp]
            min_left_index[i] = temp  # 存储左边界位置

        min_right_index[size-1] = size  # 最后一个元素的右边界为数组长度
        for i in range(size-2, -1, -1):  # 遍历数组,计算每个位置的右边界
            temp = i + 1
            while temp < size and heights[temp] >= heights[i]:  # 寻找右边第一个小于当前高度的位置
                temp = min_right_index[temp]
            min_right_index[i] = temp  # 存储右边界位置

        for i in range(size):  # 遍历数组,计算以每个位置为高度的最大矩形面积
            area = heights[i] * (min_right_index[i] - min_left_index[i] - 1)  # 计算面积
            result = max(area, result)  # 更新结果变量

        return result  # 返回最大矩形面积

这个不太好理解,min_left_index中存放的是数组对应下标的元素左边第一个小于它本身的元素的下标。min_right_index中存放的是数组对应下标的元素右边第一个小于它本身的元素的下标。
这里以数组[3, 5, 2, 4]为例:
min_left_index:
元素3的左边没有比它小的元素,所以min_left_index[0] = - 1 (注意:存放的是下标)
元素5的左边第一个比它小的元素是3,3的对应下标为0. 所以min_left_index[1] = 0
同理 min_left_index[2] = -1, min_left_index[3] = 2
min_left_index = [-1, 0, -1, 2]
min_right_index:
元素3的右边第一个小于它的元素是2,对应下标为2 所以min_right_index[0] = 2
之后一次类推
min_right_index = [2, 2, 4, 4]

单调栈:

本题单调栈的解法和接雨水的题目是遥相呼应的。

为什么这么说呢,42. 接雨水 是找每个柱子左右两边第一个大于该柱子高度的柱子,而本题是找每个柱子左右两边第一个小于该柱子的柱子。

这里就涉及到了单调栈很重要的性质,就是单调栈里的顺序,是从小到大还是从大到小。

在题解42. 接雨水 中我讲解了接雨水的单调栈从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。

那么因为本题是要找每个柱子左右两边第一个小于该柱子的柱子,所以从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序!

此时大家应该可以发现其实就是栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度

理解这一点,对单调栈就掌握的比较到位了。

除了栈内元素顺序和接雨水不同,剩下的逻辑就都差不多了,在题解42. 接雨水我已经对单调栈的各个方面做了详细讲解,这里就不赘述了。

主要就是分析清楚如下三种情况:

  • 情况一:当前遍历的元素heights[i]大于栈顶元素heights[stack[-1]]的情况
  • 情况二:当前遍历的元素heights[i]等于栈顶元素heights[stack[-1]]的情况
  • 情况三:当前遍历的元素heights[i]小于栈顶元素heights[stack[-1]]的情况

面积到底是怎样计算的呢?这里也是不太好理解的地方,依旧以[3, 5, 2, 4]为例:(重难点)

元素3对应下标进栈,5比3大,5对应下标进栈,2比5小,此时就要计算面积了,计算的是栈顶元素的面积(因为此时它的左右两边都有比它小的元素),元素5对应的面积就是 底 X 高 底是元素2的下标减去元素3的下标再减1 (right - left - 1)(右边第一个比它小的元素的下标减左边第一个比它小的元素的下标再减1) 元素5 此时已经出栈了

接下来再比较元素2和元素3, 2比3小,此时就可以计算出3的对应面积,这里计算就会出现问题,什么问题? —— 元素3的面积的底怎么计算?

这里就要在height数组前后添0

开头为什么要加元素0?

如上述例子[3, 5, 2, 4]所述那样,在求元素3的对应面积时,面积中的 right(右) 和 mid(高) 都知道, 但是得不到 left 。因为元素3出栈后栈就为空了,此时求出的元素3的面积就是0。
此时开头加个0,就会避免此类情况的发生(元素0的高度也为0,不影响计算结果)

末尾为什么要加元素0?

还是以[3, 5, 2, 4]为例,在开头加0后可以正常求出元素3的面积,之后元素2对应下标进栈,元素4对应下标也进栈,此时数组中没有元素了,但是元素2和元素4的面积还没有求出来,这时就需要在数组末尾添0,让栈里的所有元素,走到情况三的逻辑。

所以我们需要在 height数组前后各加一个元素0。

代码及详细注释:

暴力法:

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        res = 0  # 初始化结果变量为0

        for i in range(len(heights)):  # 遍历数组
            left = i  # 初始化左指针为当前位置
            right = i  # 初始化右指针为当前位置
            for _ in range(left, -1, -1):  # 从左指针位置向左遍历
                if heights[left] < heights[i]:  # 如果左侧高度小于当前高度
                    break  # 退出循环
                left -= 1  # 左指针左移
            for _ in range(right, len(heights)):  # 从右指针位置向右遍历
                if heights[right] < heights[i]:  # 如果右侧高度小于当前高度
                    break  # 退出循环
                right += 1  # 右指针右移
                
            width = right - left - 1  # 计算宽度
            height = heights[i]  # 当前位置的高度
            res = max(res, width * height)  # 计算面积并更新结果变量

        return res  # 返回最大矩形面积

双指针法:

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        size = len(heights)  # 获取数组长度
        min_left_index = [0] * size  # 初始化存储左边界的数组
        min_right_index = [0] * size  # 初始化存储右边界的数组
        result = 0  # 初始化结果变量为0

        min_left_index[0] = -1  # 第一个元素的左边界为-1
        for i in range(1, size):  # 遍历数组,计算每个位置的左边界
            temp = i - 1
            while temp >= 0 and heights[temp] >= heights[i]:  # 寻找左边第一个小于当前高度的位置
                temp = min_left_index[temp]
            min_left_index[i] = temp  # 存储左边界位置

        min_right_index[size-1] = size  # 最后一个元素的右边界为数组长度
        for i in range(size-2, -1, -1):  # 遍历数组,计算每个位置的右边界
            temp = i + 1
            while temp < size and heights[temp] >= heights[i]:  # 寻找右边第一个小于当前高度的位置
                temp = min_right_index[temp]
            min_right_index[i] = temp  # 存储右边界位置

        for i in range(size):  # 遍历数组,计算以每个位置为高度的最大矩形面积
            area = heights[i] * (min_right_index[i] - min_left_index[i] - 1)  # 计算面积
            result = max(area, result)  # 更新结果变量

        return result  # 返回最大矩形面积

单调栈:

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        size = len(heights)  # 获取数组长度
        min_left_index = [0] * size  # 初始化存储左边界的数组
        min_right_index = [0] * size  # 初始化存储右边界的数组
        result = 0  # 初始化结果变量为0

        min_left_index[0] = -1  # 第一个元素的左边界为-1
        for i in range(1, size):  # 遍历数组,计算每个位置的左边界
            temp = i - 1
            while temp >= 0 and heights[temp] >= heights[i]:  # 寻找左边第一个小于当前高度的位置
                temp = min_left_index[temp]
            min_left_index[i] = temp  # 存储左边界位置

        min_right_index[size-1] = size  # 最后一个元素的右边界为数组长度
        for i in range(size-2, -1, -1):  # 遍历数组,计算每个位置的右边界
            temp = i + 1
            while temp < size and heights[temp] >= heights[i]:  # 寻找右边第一个小于当前高度的位置
                temp = min_right_index[temp]
            min_right_index[i] = temp  # 存储右边界位置

        for i in range(size):  # 遍历数组,计算以每个位置为高度的最大矩形面积
            area = heights[i] * (min_right_index[i] - min_left_index[i] - 1)  # 计算面积
            result = max(area, result)  # 更新结果变量

        return result  # 返回最大矩形面积

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

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

相关文章

MQTT在linux下服务端和客户端的应用

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级、开放标准的消息传输协议&#xff0c;设计用于受限设备和低带宽、不稳定网络的通信。 MQTT的一些关键特点和概念&#xff1a; 发布/订阅模型&#xff1a; MQTT采用发布/订阅&#xff08;Publ…

【typescript】特殊符号用法(?:)(??)(?.)(!)(!!)

一. 问号冒号&#xff08;?:&#xff09; 1.可以作为对象类型的可选属性&#xff0c;如&#xff1a; interface Person{name : string;age?: number; }const person1 : Person {name:"zien"} const person2 : Person {name:"sad", age:18} console.l…

【Unity】QFramework通用背包系统优化:使用Odin优化编辑器

前言 在学习凉鞋老师的课程《QFramework系统设计&#xff1a;通用背包系统》第四章时&#xff0c;笔者使用了Odin插件&#xff0c;对Item和ItemDatabase的SO文件进行了一些优化&#xff0c;使物品页面更加紧凑、更易拓展。 核心逻辑和功能没有改动&#xff0c;整体代码量减少…

蓝桥杯-求阶乘-python

问题描述 满足N!的末尾恰好有K个0的最小的N是多少&#xff1f; 如果这样的N不存在输出一1。 思路解析 末尾的0是由10产生的&#xff0c;而10是由质数2和5产生的 在求阶乘的过程中&#xff0c;只要是偶数就会有2&#xff0c;而5相对2更少&#xff0c;所以对于10的数量我们可以…

【分享】Word快捷键--Tab键的应用技巧

在使用word编辑文档时&#xff0c;想必大家一定经常用到【Tab】这个快捷键&#xff0c;今天来分享几个Tab键的应用技巧&#xff0c;这些技巧在文档排版中大有用处&#xff0c;可以大大提高我们的操作效率。 1.段首空两格 写文章时&#xff0c;只需按下【Tab】键就可以自动缩进…

Java串口通信技术探究2:RXTX库单例测试及应用

目录 一、创建串口工具类二、串口工具测试三、运行时会遇到的错误JVM崩溃无法找到指定的类 本文主要介绍了Java串口通信技术探究&#xff0c;重点分析了RXTX库单例测试以及串口工具的使用。通过实例演示了如何使用SerialPortTool类进行串口操作&#xff0c;包括打开串口、关闭串…

MySQL篇----第十一篇

系列文章目录 文章目录 系列文章目录前言一、BLOB 和 TEXT 有什么区别?二、MySQL_fetch_array 和 MySQL_fetch_object 的区别是什么?三、MyISAM 表格将在哪里存储,并且还提供其存储格式?四、MySQL 如何优化 DISTINCT?五、如何显示前 50 行?前言 前些天发现了一个巨牛的人…

ProtonMail邮箱怎么样?国内有什么替代品?

ProtonMail作为业界知名的加密邮箱提供者&#xff0c;其安全性、隐私保护等特性让不少追求私密通信的用户趋之若鹜。然而对于国内用户而言&#xff0c;ProtonMail可能并非最佳选择&#xff0c;受限于许多因素&#xff0c;从语言支持到服务器位置再到可访问性&#xff0c;都可能…

parse库,一个优雅的python库

前言 在Python中&#xff0c;format方法和f-strings是两种常用的字符串插值方法。 name "Haige" age "18" print(f"{name} is {age} years old.")# Haige is 18 years old.而如果是要从字符串中提取期望的值呢&#xff1f;相信很多人的第一或…

tkinter绘制组件(41)——菜单按钮

tkinter绘制组件&#xff08;41&#xff09;——菜单按钮 引言布局函数结构按钮部分菜单显示完整代码函数 效果测试代码最终效果 github项目pip下载结语 引言 TinUI5的新控件&#xff0c;菜单按钮&#xff0c;menubutton。 这是一个与TinUI菜单&#xff08;menubar&#xff0…

【C++】基础知识讲解(引用、内联、auto,基于范围for循环)

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;http://t.csdnimg.cn/eCa5z 目录 引用 概念 特性 使用场景 作参数 作返回值 传值、传引用效率比较 引用和指针的区别 内联函数 概念…

excel 导出 The maximum length of cell contents (text) is 32767 characters

导出excel报错。错误日志提示&#xff1a;:The maximum length of cell contents (text) is 32767 characters 排查后&#xff0c;发现poi有单元格最大长度校验&#xff0c;超过32767会报错。 解决方案&#xff1a; 通过java反射机制&#xff0c;设置单元格最大校验限制为Int…

Skywalking 应用笔记

概念 Skywalking是一款分布式的系统 性能监视工具&#xff0c;专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。SkyWalking是一款 观察性的分析平台和应用性能管理系统&#xff0c;提供了 分布式追踪、性能指标分析、应用服务依赖分析、可视化一体化等解决方…

CV | SAM在医学影像上的模型调研【20240207更新版】

本文主要是SAM&#xff08;Segment Anything&#xff09;在医学影像上的数据集&#xff0c;模型及评估方法调研【持续更新】~ 1.开源数据集 可参考这篇【数据集 | 基于计算机视觉的医学影像处理数据集_CSDN博客】 2.算法模型 2023.04_SAM 论文&#xff1a;2018.08.05v_Segm…

Win32 SDK Gui编程系列之--弹出式菜单

1.弹出式菜单 例如,在命令提示窗口中点击鼠标右键,会出现如下图所示的弹出菜单(下拉菜单)。 这种弹出式菜单的实现很简单。不创建菜单栏,用CreatePopupMenu函数创建的菜单是最顶端的菜单就可以了。 菜单的显示使用TrackPopupMenu函数进行。 例如,点击鼠标右键显示弹出…

尚硅谷 Java 基础实战—Bank 项目—实验题目 3

实验题目 修改 withdraw 方法以返回一个布尔值&#xff0c;指示交易是否成功。 实验目的 使用有返回值的方法。 提示 修改 Account 类 修改 deposit 方法返回 true&#xff08;意味所有存款是成功的&#xff09;。修改 withdraw 方法来检查提款数目是否大于余额。如果amt小…

十七、vben合并行后操作按钮如何合并

上期我们说了如何在table内部合并行,行内的内容都是字符串,那么如果是多个操作按钮呢,他们是如何合并的,事件是怎么触发的,怎么写呢。 先看效果图 数据上也是和上期一样有9条信息。 下面来看一下我们的具体实现 一、在template里面写table <BasicTable:showIndexCol…

【网络技术】【Kali Linux】Nmap 嗅探(一)简单扫描

一、实验环境 本次实验进行简单的Nmap扫描&#xff0c;实验使用 Kali Linux 虚拟机和 Ubuntu Linux 虚拟机完成&#xff0c;主机操作系统为 Windows 11&#xff0c;虚拟化平台选择 Oracle VM VirtualBox&#xff0c;如下图所示。 二、实验步骤 1、相关配置 Kali Linux 虚拟机…

【python】python实现代码雨【附源码】

欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 系列文章 1新年烟花代码https://blog.csdn.net/m0_73367097/article/details/1354817792爱心代码https://blog.csdn.net/m0_73367097/article/details/136017032 一、效果图&#xff1a; 二、准备工作 &#xff08;1…

第二证券:股市的国家队是谁?股市国家队包括哪些机构?

在a股商场上&#xff0c;投资者大致能够分为散户、游资、主力、组织、国家队这几大类&#xff0c;那么&#xff0c;股市的国家队是谁&#xff1f;股市国家队包含哪些组织&#xff1f; 国家队主要是指以下五大类&#xff1a; 1、中心汇金 中心汇金的全称为中心汇金投资有限责…