力扣: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  # 初始化结果变量为0max_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 += rainreturn 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.popstack.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] - 1res += 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  # 初始化结果变量为0max_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 += rainreturn res  # 返回最终的积水总量

单调栈:

class Solution:def trap(self, height: List[int]) -> int:res = 0  # 初始化结果变量为0stack = [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  # 初始化结果变量为0for 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  # 初始化结果变量为0min_left_index[0] = -1  # 第一个元素的左边界为-1for i in range(1, size):  # 遍历数组,计算每个位置的左边界temp = i - 1while 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 + 1while 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  # 初始化结果变量为0for 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  # 初始化结果变量为0min_left_index[0] = -1  # 第一个元素的左边界为-1for i in range(1, size):  # 遍历数组,计算每个位置的左边界temp = i - 1while 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 + 1while 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  # 初始化结果变量为0min_left_index[0] = -1  # 第一个元素的左边界为-1for i in range(1, size):  # 遍历数组,计算每个位置的左边界temp = i - 1while 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 + 1while 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.mzph.cn/news/673304.shtml

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

相关文章

AMD64 linux 环境中,如何将main.go打包成不带 .exe 的可执行文件?

在终端中先进入main.go所在的文件夹&#xff0c;然后运行这三条命令即可 $env:GOOS"linux" $env:GOARCH"amd64" go build main.go 最终结果&#xff0c;成功出现不带 .exe 结尾的可执行包&#xff1a;

日本失去的三十年:去杠杆用了14年

去年以来&#xff0c;日股在日本央行转鹰预期、基本面改善和一系列监管新规的催化下高歌猛进&#xff0c;日经指数已经逼近90年代资产泡沫时期的高位。今年迄今累计上涨8.51%&#xff0c;领跑全球&#xff0c;“失落的三十年”似乎已经远去。 日本因何走向衰退&#xff1f;“失…

【C语言】位与移位操作符详解

目录 1.⼆进制和进制转换 ①十进制&#xff1a;生活中最常用 ②二进制&#xff1a;计算机中使用的&#xff0c;每个数字称为一个比特 ③八进制、十六进制也如上 ④二进制转十进制 ⑤十进制转二进制 ⑥二进制转八进制 ⑦二进制转十六进制 2.原码、反码、补码 3.移位操…

【已更新】2024美赛C题代码教学思路数据处理数学建模分析Momentum in Tennis

问题一完整的代码已给出&#xff0c;预计2号晚上或者3号凌晨全部给出。 代码逻辑如下&#xff1a; C题第一问要求我们开发一个模型&#xff0c;捕捉得分时的比赛流程&#xff0c;并将其应用于一场或多场比赛。你的模型应该确定哪名球员在比赛的特定时间表现得更好&#xff0c;…

AI-数学-高中-24-三角函数一般形式的各参数含义

原作者视频&#xff1a;三角函数】12三角函数一般形式的各参数含义&#xff08;易&#xff09;_哔哩哔哩_bilibili 1.函数中的A标识符&#xff1a;表示曲线中间平衡位置的振幅&#xff0c;值域为正负A&#xff1a;[-A,A]。 2.函数中的B标识符&#xff1a;决定曲线纵向上下平移…

基于 SpringBoot 和 Vue.js 的权限管理系统部署教程

大家后&#xff0c;我是 jonssonyan 在上一篇文章我介绍了我的新项目——基于 SpringBoot 和 Vue.js 的权限管理系统&#xff0c;本文主要介绍该系统的部署 部署教程 这里使用 Docker 进行部署&#xff0c;Docker 基于容器技术&#xff0c;它可以占用更少的资源&#xff0c;…

linux文件的IO函数

open函数: 作用&#xff1a;打开或者新建一个文件 原型&#xff1a; int open(const char*pathname,int flags); int open(const char*pathname,int flags,mode_t mode); 参数&#xff1a; pathname:路径 flags:1-> O_RONLY 只读打开 2 -> O_WONLY只写打开 3->…

83 CTF夺旗-Python考点SSTI反序列化字符串

这里写目录标题 CTF各大题型简介演示案例:CTF夺旗-Python-支付逻辑&JWT&反序列化CTF夺旗-Python-Flask&jinja2&SSTl模版注入CTF夺旗-Python-格式化字符串漏洞&读取对象 涉及资源&#xff1a; 我们这篇文章主要讲的是CTF在web渗透测试方向的3个考点 CTF各大…

elementui常用组件-个人版(间断更新)

Dialog 对话框 el-dialog <el-dialogtitle"提示":visible.sync"dialogVisible"width"30%":before-close"handleClose"><span>这是一段信息</span><span slot"footer" class"dialog-footer"…

微信小程序(三十六)事件传参

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.传参步骤 2.传参接收解构步骤 源码&#xff1a; index.wxml <button type"primary" bind:tap"onclick" mark:index"{{0}}" mark:remb"{{1}}" class"But&quo…

产品经理--分享在项目中产品与研发之间会遇到的问题 在面试这一岗位时,面试官常问的问题之一,且分享两大原则来回答面试官这一问题

目录 一.STAR原则 1.1 简介 1.2 如何使用 1.3 举例说明 二.PDCA原则 2.1 简介 2.2 如何使用 2.3 运用场景 2.4 举例说明 三.产品与研发的沟通痛点 3.1 沟通痛点的原因 3.2 分享案例 前言 本篇会详细阐明作为一个产品经理会在项目遇到的问题&#xff0c;如&#xff1a;产…

张艺谋《主角》选角引发热议,周迅、赵丽颖、杨紫或成候选。

♥ 为方便您进行讨论和分享&#xff0c;同时也为能带给您不一样的参与感。请您在阅读本文之前&#xff0c;点击一下“关注”&#xff0c;非常感谢您的支持&#xff01; 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 近日&#xff0c;张艺谋执导的首部电视剧《主角》女主选角成为…

6.electron之上下文隔离,预加载JS脚本

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 Electron 将 Chromium 和 Node.js 嵌入到了一个二进制文件中&#xff0c;因此它允许你仅需一个代码仓库&#xff0c;就可以撰写支持 Windows、…

【Linux】vim的基本操作与配置(上)

Hello everybody!今天我们要进入vim的讲解了。学会了vim,咱们就可以在Linux系统上做一些简单的编程啦&#xff01; 那么废话不多说&#xff0c;咱们直接进入正题&#xff01; 1.初识vim vim是一款多模式的文本编辑器&#xff0c;可以对一个文件进行编辑操作。 它一共有三个模…

2024年【化工自动化控制仪表】最新解析及化工自动化控制仪表考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【化工自动化控制仪表】最新解析及化工自动化控制仪表考试资料&#xff0c;包含化工自动化控制仪表最新解析答案和解析及化工自动化控制仪表考试资料练习。安全生产模拟考试一点通结合国家化工自动化控制仪表考…

《dx12 龙书》第四部分学习笔记——预备知识(下)

7、多重采样技术的原理 由于屏幕中显示的像素不可能是无穷小的&#xff0c;所以并不是任意一条直线都能在显示器上“平滑”而完美地呈现出来。即为以像素矩阵 &#xff08;matrix of pixels&#xff0c; 可以理解为“像素2D数组”&#xff09;逼近直线的方法所产生的“阶梯” &…

EDM营销平台哪个好?推荐的邮件营销平台?

EDM邮件营销平台有哪些&#xff1f;外贸EDM邮件营销平台有哪些&#xff1f; EDM营销平台已成为企业推广产品和服务的重要工具。但是&#xff0c;面对市场上众多的EDM营销平台&#xff0c;究竟哪个更好呢&#xff1f;下面&#xff0c;蜂邮EDM将从平台功能、用户体验、数据分析和…

Matlab使用点云工具箱进行点云配准

一、代码 source_pc pcread(bun_zipper.ply); target_pc pcread(bun_zipper2.ply); % 下采样 gridStep 0.001; ptCloudA pcdownsample(source_pc,gridAverage,gridStep); ptCloudB pcdownsample(target_pc,gridAverage,gridStep); % 初始变换矩阵 tform_initial affine3…

C语言笔试题之实现C库函数 pow()(递归的思想)

实例要求&#xff1a; 1、请你实现C库函数 pow()&#xff08;stdio.h & math.h&#xff09; &#xff0c;即计算 x 的整数 n 次幂函数&#xff08;即x^n &#xff09;&#xff1b;2、函数声明&#xff1a;double myPow(double x, int n)&#xff1b;参数&#xff1a;1、x …

YOLOv8改进 更换轻量级网络结构

一、GhostNet论文 论文地址:1911.11907.pdf (arxiv.org) 二、 GhostNet结构 GhostNet是一种高效的目标检测网络,具有较低的计算复杂度和较高的准确性。该网络采用了轻量级的架构,可以在计算资源有限的设备上运行,并能够快速地实时检测图像中的目标物体。 GhostNet基于Mo…