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

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

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.mfbz.cn/a/372913.html

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

相关文章

CIFS(Samba)服务的使用

理论部分 概念&#xff1a; 通用互联网文件系统CIFS使用的是公共的或者开放的SMB协议版本。SMB是在会话层和表示层以及小部分应用层上的 协议&#xff0c;使用了NetBIOS的应用程序接口API。该协议在局域网上用于服务器文件访问和打印。它使用客户/服务器模式&#xff0c;客 户…

ffmpeg的使用,安装,抽帧,加水印,截图,生成gif,格式转换,抓屏等

实际使用中总结的关于ffmpeg对视频的处理的记录文档 具体信息&#xff1a; http://ffmpeg.org/download.html 官网下载ffmpeg 关于ffmpeg的安装详细步骤和说明 装ffmpeg 方式,Linux和windows下的 http://bbs.csdn.net/topics/390519382 php 调用ffmpeg , http://bbs.csdn.net/t…

【算法】利用递归dfs解决二叉树算法题(C++)

文章目录 1. 前言2. 算法题2331.计算布尔二叉树的值129.求根节点到叶节点数字之和LCR047.二叉树剪枝98.验证二叉搜索树230.二叉搜索树中第K小的元素257.二叉树的所有路径 1. 前言 有关 递归 的相关解释与解题 请看下文&#xff1a; 以汉诺塔理解递归、并用递归解决算法题 对于…

关于Linux和消息队列常见的十道面试题

实际工作中如何排查CPU飙升问题&#xff1f; 在实际工作中&#xff0c;我们可以通过以下步骤来排查CPU飙升的问题&#xff1a; 使用系统监控工具&#xff1a;首先&#xff0c;我们可以使用系统监控工具&#xff0c;如top命令&#xff0c;来查看所有进程占系统CPU的排序。这样可…

AI助力农作物自动采摘,基于YOLOv7【tiny/l/x】不同系列参数模型开发构建作物生产场景下番茄采摘检测计数分析系统

去年十一那会无意间刷到一个视频展示的就是德国机械收割机非常高效自动化地24小时不间断地在超广阔的土地上采摘各种作物&#xff0c;专家设计出来了很多用于采摘不同农作物的大型机械&#xff0c;看着非常震撼&#xff0c;但是我们国内农业的发展还是相对比较滞后的&#xff0…

【深度学习】从0完整讲透深度学习第2篇:TensorFlow介绍和基本操作(代码文档已分享)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论深度学习相关知识。可以让大家熟练掌握机器学习基础,如分类、回归&#xff08;含代码&#xff09;&#xff0c;熟练掌握numpy,pandas,sklearn等框架使用。在算法上&#xff0c;掌握神经网络的数学原理&#xff0c;手动实…

2024数学建模美赛F题Reducing Illegal Wildlife Trade原创论文讲解(含完整python代码)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了数学建模美赛本次F题目非法野生动物贸易完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 F题论文共42页&…

MySQL温故篇(一)SQL语句基础

一、SQL语句基础 1、SQL语言分类 DDL&#xff1a;数据定义语言 DCL&#xff1a;数据控制语言 DML&#xff1a;数据操作语言 DQL&#xff1a;数据的查询语言 2、数据类型 3、字符类型 char(11) &#xff1a; 定长 的字符串类型,在存储字符串时&#xff0c;最大字符长度11个&a…

PiflowX新增Apache Beam引擎支持

参考资料&#xff1a; Apache Beam 架构原理及应用实践-腾讯云开发者社区-腾讯云 (tencent.com) 在之前的文章中有介绍过&#xff0c;PiflowX是支持spark和flink计算引擎&#xff0c;其架构图如下所示&#xff1a; 在piflow高度抽象的流水线组件的支持下&#xff0c;我们可以…

【C/C++】C/C++编程——整型(二)

在 C 中&#xff0c;整型数据可以分为有符号数&#xff08;Signed&#xff09;和无符号数&#xff08;Unsigned&#xff09;&#xff0c;这两种类型主要用于表示整数值&#xff0c;但它们在表示范围和用途方面有所不同。默认情况下&#xff0c;整数类型如 int、short、long 都是…

爱上JUC: 面试常考题大总结(线程安全篇)

&#x1f31f;一起备战面试吧&#x1f604;&#xff0c;也是巩固&#x1f4aa;&#xff0c;不再害怕面试&#x1f44a; 文章目录 进程和线程区别并行和并发的区别创建线程的方式有哪些runnable和callable有什么区别run和start区别线程包含哪些状态&#xff0c;是如何转换的&…

【TCP/IP】用户访问一个购物网站时TCP/IP五层参考模型中每一层的功能

当用户访问一个购物网站时&#xff0c;网络上的每一层都会涉及不同的协议&#xff0c;具体网络模型如下图所示。 以下是每个网络层及其相关的协议示例&#xff1a; 物理层&#xff1a;负责将比特流传输到物理媒介上&#xff0c;例如电缆或无线信号。所以在物理层&#xff0c;可…

DockerUI如何部署结合内网穿透实现公网环境管理本地docker容器

文章目录 前言1. 安装部署DockerUI2. 安装cpolar内网穿透3. 配置DockerUI公网访问地址4. 公网远程访问DockerUI5. 固定DockerUI公网地址 前言 DockerUI是一个docker容器镜像的可视化图形化管理工具。DockerUI可以用来轻松构建、管理和维护docker环境。它是完全开源且免费的。基…

基于协同算法的图书信息管理系统(编号V73)

Java精品项目源码基于协同算法的图书信息管理系统(编号V73) 大家好&#xff0c;小辰今天给大家介绍一个图书信息管理系统&#xff0c;演示视频公众号&#xff08;小辰哥的Java&#xff09;对号查询观看即可 文章目录 Java精品项目源码基于协同算法的图书信息管理系统(编号V73…

Pandas.Series.cumsum() 累积和 详解 含代码 含测试数据集 随Pandas版本持续更新

关于Pandas版本&#xff1a; 本文基于 pandas2.2.0 编写。 关于本文内容更新&#xff1a; 随着pandas的stable版本更迭&#xff0c;本文持续更新&#xff0c;不断完善补充。 传送门&#xff1a; Pandas API参考目录 传送门&#xff1a; Pandas 版本更新及新特性 传送门&…

医学答案怎么查找?3个受欢迎的搜题分享了 #其他#职场发展#职场发展

学习工具是我们的得力助手&#xff0c;帮助我们更好地组织学习内容和时间。 1.南北题库 这是一个网站 完全免费,主要的特点就是题库全面丰富,涵盖计算机、外语、论文撰写、注册会计师等。并且后续还会继续扩展题库,题目分类非常详细,体界面清晰简洁。 有举一反三功能,搜一道…

使用PHPStudy搭建本地web网站并实现任意浏览器公网访问

文章目录 [toc]使用工具1. 本地搭建web网站1.1 下载phpstudy后解压并安装1.2 打开默认站点&#xff0c;测试1.3 下载静态演示站点1.4 打开站点根目录1.5 复制演示站点到站网根目录1.6 在浏览器中&#xff0c;查看演示效果。 2. 将本地web网站发布到公网2.1 安装cpolar内网穿透2…

正点原子--STM32定时器学习笔记(1)

这部分是笔者对基本定时器的理论知识进行学习与总结&#xff01;&#xff0c;主要记录自己在学习过程中遇到的重难点&#xff0c;其他一些基础点就一笔带过了&#xff01; 1. 定时器概述 1.1 软件定时原理 使用纯软件&#xff08;CPU死等&#xff09;的方式实现定时&#xf…

【SpringBoot】SpringBoot的web开发

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;SpringBoot ⛺️稳重求进&#xff0c;晒太阳 Wbe开发 使用Springboot 1&#xff09;、创建SpringBoot应用&#xff0c;选中我们需要的模块&#xff1b; 2&#xff09;、SpringBoot已经默…

机器视觉系统设计:视觉系统中的成像基准

开发视觉系统的一个重要活动是验证其部署是否符合工程规范。一个成功的视觉应用程序的两个特点是它无需工程师干涉情况下正常工作了多长时间&#xff0c;以及它的维护和复制部署是多么简易。实现所有如上所述目标的一个关键步骤是确定视觉系统的基准。 在这里使用的上下文中&a…
最新文章