辽宁钢绞线_天津瑞通预应力钢绞线

陇南15.2钢绞线规格及参数 2026-08-26: 矩阵中的局部大值Ⅱ。用go话语, 给定个大小为 n

发布日期:2026-08-28 12:22点击次数:106

钢绞线

2026-08-26:矩阵中的局部大值Ⅱ。用go话语陇南15.2钢绞线规格及参数,给定个大小为 n 行 m 列的整数矩阵,矩阵里所少见字都是大于等于 0 的。

关于矩阵中淘气个数值大于 0 的格子(称为“现时格子”),咱们以它的数值当作半径,检讨它周围的个特定区域:

• 这个区域包括:以现时格子为中心,朝上、下、左、右各蔓延“现时数值”那么多行的悉数格子。

• 然而,要摒除那些行向和列向的距离都恰好等于现时数值的格子(也即是四个角上的远点)。

• 同期,出矩阵领域的格子不纳入斟酌。

若是现时格子安闲以下两个条款,就称它为“局部大值”:

1. 它自己的值大于 0;

2. 在上述悉数被斟酌的格子中,莫得任何个格子的数值比现时格子的数值大(也即是现时格子的值是这些斟酌鸿沟内的大值,允许相等)。

后,你需要统计通盘矩阵中这么的“局部大值”共有若干个,并复返这个数目。

1

1

0

输入: matrix = [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,2,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]]。

输出: 1。

在这里插入图片态状

发挥:

关于非单位格 (3, 3) ,x = matrix[3][3] = 2 。

亮的单位格是在 (3, 3) 的 x 行和 x 列鸿沟内被斟酌的单位格。

行距离和列距离都等于 x = 2 的四个单位格被忽略。

莫得个被斟酌的单位格的值大于 2 ,因此 (3, 3) 是个局部大值。

莫得其他非单位格,是以谜底是 1 。

题目来独力扣3933。

步:问题中枢逻辑领会

题目要求:

• 关于每个 > 0 的格子 (i, j),其值为 x。

• 要检讨个以它为中心、半径 x 的形区域(高下附近各蔓延 x 行/列)。

• 然而,四个角的格子(即行差 == x 且 列差 == x 的位置)要摒除在外。

• 若是该区域内莫得比它大的数,就计数为“局部大值”。

这里“莫得大”的道理是不错有相等的值。

二步:代码的举座结构

代码使用了 线段树 + 维ST表 的二维鸿沟大值查询结构。

主要结构:

• 维ST表(sparseTable):不错快速查询维数组淘气区间的大值。

• 线段树(seg):每个节点爱戴的是个维ST表,这个ST表代表某段都集行在每列上的大值。

三步:构建数据结构

1. 维ST表

• 输入个数组 a 和并函数 op(这里是 max)。

• 构建 st 二维数组,st[k][j] 默示从 j 入手长度为 2^k 的区间的大值。

• 查询 query(l, r) 时,运用 bits.Len8 快速得到区间长度对应的 k,然后并两个重迭区间取大值。

• 这里因为数据鸿沟 ≤ 200,使用 bits.Len8 是安全的。

2. 线段树节点

• 线段树每个节点代表个行区间 [l, r]。

• 叶子节点:径直对 matrix[l](行)设置维ST表。

• 里面节点:

• 先区分构建附近子树。

• 取附近子树根节点(即对应行区间)的st[0](长度为 m 的数组)逐列取大值,酿成新的长度为 m 的数组。

• 再对这个新数组设置维ST表。

这么,每个线段树节点就保存了该行区间内,每列的大值,而况撑合手快速查询淘气列区间。

四步:查询过程

关于每个格子 (i, j),值 x:

• 咱们要检讨两个矩形区域的大值:

1. 区域A:行鸿沟 [max(i-x, 0), min(i+x, n-1)],列鸿沟 [max(j-x+1, 0), min(j+x, m)](提防列左边少1,右边含j+x,从而避让四个角中的附近角)。

2. 区域B:行鸿沟 [max(i-x+1, 0), min(i+x-1, n-1)],列鸿沟 [max(j-x, 0), min(j+x+1, m)](行鸿沟高下迟滞行,列鸿沟膨胀格,亦然避让四个角)。

这两个区域起来未必即是去除四个角的竣工形区域(因为四个角在这两个区域里都被区分摒除了)。

• 调用线段树的 query 法,区分得到区域A和区域B的大值。

• 若是这两个大值都 ≤ x,则现时格子是局部大值,计数加。

五步:线段树的 query 过程

query(node, l, r, r1, r2, c1, c2):

• node:现时节点,科罚行区间 [l, r]。

• [r1, r2]:要查询的行鸿沟。

• [c1, c2):要查询的列鸿沟(左闭右开)。

• 若是现时节点被 [r1, r2] 包含,钢绞线厂家则径直复返该节点上ST表对列区间的查询后果。

• 不然,凭证 [r1, r2] 与附近子树的错杂,递归查询附近子树,并取大值复返。

六步:主经由

1. 得到矩阵大小 n, m。

2. 构建线段树,大小凭证 n 计较(2

3. 调用 build 填充线段树。

4. 双重轮回遍历悉数格子:

• 只处理值 > 0 的格子。

• 计较两个区域的行列鸿沟。

• 查询两个区域的大值。

• 若是二者均 ≤ 现时值,则 ans++。

5. 输出 ans。

七步:例子考证

给定全 0 矩阵,中间个 2:

• 关于 (3,3),x=2:

• 区域A:行[1,5],列[2,5](摒除左上角(1,1)和右上角(1,5))

• 区域B:行[2,4],列[1,6](摒除左下角(5,1)和右下角(5,5))

• 这两个区域起来即是除了四个角以外的通盘 5x5 形。

• 一谈为0,大值0 ≤ 2,是以安闲条款,计数为1。

• 其他格子值为0,不处理。

• 终输出1。

时辰与空间复杂度

时辰复杂度

• 构建线段树:

• 每个节点要构建维ST表,ST表构建复杂度 O(m log m)。

• 共有 O(n) 个节点(线段树节点数约 4n),是以构建总复杂度 O(n * m log m)。

• 查询:

• 每次查询需要 O(log n) 个线段树节点,每个节点作念次ST表查询 O(1)。

• 每个格子多作念 2 次查询,格子总额 n*m。

• 是以总查询复杂度 O(n*m * log n)。

总时辰复杂度:O(n * m * (log m + log n)),在 n,m ≤ 200 时相等快。

特等空间复杂度

• 线段树每个节点存储个ST表,每个ST表是二维数组,大小约 log m × m。

• 节点数 O(n),是以总空间 O(n * m * log m)。

• 加上矩阵自己 O(n*m)。

总的特等空间复杂度:O(n * m * log m)。

Go竣工代码如下:

.

package main

import (

"fmt"

"math/bits"

)

// 维 ST 表(泛型版块)

type sparseTable[T any] struct {

st [][]T

op func(T, T) T

}

func newSparseTable[T any](a []T, op func(T, T) T) sparseTable[T] {

n := len(a)

w := bits.Len(uint(n))

st := make([][]T, w)

for i := range st {

st[i] = make([]T, n)

}

st[0] = a

for i := 1; i

for j := range n - 1

st[i][j] = op(st[i-1][j], st[i-1][j+1

}

}

return sparseTable[T]{st, op}

}

func (s sparseTable[T]) query(l, r int) T {

k := bits.Len8(uint8(r-l)) - 1 // 本题数据鸿沟小,不错用 Len8

return s.op(s.st[k][l], s.st[k][r-1

}

// 竣工模板见 https://leetcode.cn/circle/discuss/mOr1u6/

type seg []sparseTable[int]

func (t seg) build(a [][]int, node, l, r int) {

if l == r { // 叶子

t[node] = newSparseTable(a[l], func(a, b int) int { return max(a, b) })

return

}

m := (l + r) / 2

t.build(a陇南15.2钢绞线规格及参数, node*2, l, m) // 开动化左子树

t.build(a, node*2+1, m+1, r) // 开动化右子树

merged := make([]int, len(a[0]))

for i := range merged {

merged[i] = max(t[node*2].st[0][i], t[node*2+1].st[0][i]) // 行号 [l, r] 中的 i 列的大值

}

t[node] = newSparseTable(merged, func(a, b int) int { return max(a, b) })

}

// 行号闭区间 [r1, r2],列号左闭右开 [c1, c2)

func (t seg) query(node, l, r, r1, r2, c1, c2 int) int {

if r1

return t[node].query(c1, c2)

}

m := (l + r) / 2

if r2

return t.query(node*2, l, m, r1, r2, c1, c2)

}

if r1 > m { // [r1, r2] 在右子树

return t.query(node*2+1, m+1, r, r1, r2, c1, c2)

}

return max(t.query(node*2, l, m, r1, r2, c1, c2), t.query(node*2+1, m+1, r, r1, r2, c1, c2))

}

func countLocalMaximums(matrix [][]int) (ans int) {

n, m := len(matrix), len(matrix[0])

// 线段树每个节点 [l, r] 保存的是,当高下领域固定为 l 和 r 时,把每列的大值视作个 int,这 m 个数的维 ST 表

t := make(seg, 2

t.build(matrix, 1, 0, n-1)

for i, row := range matrix {

for j, x := range row {

if x > 0 && max(t.query(1, 0, n-1, max(i-x, 0), min(i+x, n-1), max(j-x+1, 0), min(j+x, m)),

t.query(1, 0, n-1, max(i-x+1, 0), min(i+x-1, n-1), max(j-x, 0), min(j+x+1, m)))

ans++

}

}

}

return

}

func main {

matrix := [][]int{{0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 2, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}}

result := countLocalMaximums(matrix)

fmt.Println(result)

}

Python竣工代码如下:

.

# -*-coding:utf-8-*-

from math import log2, ceil

from typing import List, Callable, TypeVar, Generic

T = TypeVar('T')

class SparseTable(Generic[T]):

"""维ST表"""

def __init__(self, arr: List[T], op: Callable[[T, T], T]):

self.op = op

n = len(arr)

if n == 0:

self.st = []

return

# 计较log2

k = n.bit_length

self.st = [[0] * n for _ in range(k)]

self.st[0] = arr[:] # 复制数组

for i in range(1, k):

step = 1

for j in range(n - (1

self.st[i][j] = op(self.st[i-1][j], self.st[i-1][j + step])

def query(self, l: int, r: int) -> T:

"""查询闭区间 [l, r] 的聚后果"""

if l > r:

# 复返个小值,用于max操作

return float('-inf') if isinstance(self.op(0, 0), (int, float)) else None

length = r - l + 1

k = length.bit_length - 1

return self.op(self.st[k][l], self.st[k][r - (1

class SegmentTree:

"""线段树,每个节点存储对应行区间的维ST表"""

def __init__(self, matrix: List[List[int]]):

self.matrix = matrix

self.n = len(matrix)

self.m = len(matrix[0]) if matrix else 0

# 计较线段树大小

size = 1

while size

size

self.tree = [None] * (2 * size)

self.size = size

self._build(1, 0, self.n - 1)

def _build(self, node: int, l: int, r: int):

"""构建线段树"""

if l == r:

# 叶子节点:径直使用该行的ST表

self.tree[node] = SparseTable(self.matrix[l], max)

return

mid = (l + r) // 2

self._build(node * 2, l, mid)

self._build(node * 2 + 1, mid + 1, r)

# 并附近子树:对每列取大值

merged = [

max(self.tree[node * 2].st[0][j], self.tree[node * 2 + 1].st[0][j])

for j in range(self.m)

]

self.tree[node] = SparseTable(merged, max)

def query(self, r1: int, r2: int, c1: int, c2: int) -> int:

"""

查询行区间 [r1, r2],列区间 [c1, c2] 的大值

"""

if r1 > r2 or c1 > c2:

return float('-inf')

return self._query(1, 0, self.n - 1, r1, r2, c1, c2)

def _query(self, node: int, l: int, r: int, r1: int, r2: int, c1: int, c2: int) -> int:

"""里面递归查询"""

if r1

return self.tree[node].query(c1, c2)

mid = (l + r) // 2

if r2

return self._query(node * 2, l, mid, r1, r2, c1, c2)

if r1 > mid:

return self._query(node * 2 + 1, mid + 1, r, r1, r2, c1, c2)

left_val = self._query(node * 2, l, mid, r1, r2, c1, c2)

right_val = self._query(node * 2 + 1, mid + 1, r, r1, r2, c1, c2)

return max(left_val, right_val)

def count_local_maximums(matrix: List[List[int]]) -> int:

"""

计较矩阵中局部大值的数目

"""

if not matrix or not matrix[0]:

return 0

n, m = len(matrix), len(matrix[0])

# 构建线段树

seg_tree = SegmentTree(matrix)

ans = 0

for i in range(n):

for j in range(m):

x = matrix[i][j]

if x == 0:

continue

# 计较需要检讨的四个区域

# 区域1:行鸿沟 [i-x, i+x],列鸿沟 [j-x+1, j+x]

# 区域2:行鸿沟 [i-x+1, i+x-1],列鸿沟 [j-x, j+x+1]

# 提防:摒除四个角

# 本色上原Go代码用两次查询作念了笼罩,咱们保合手致

r1_1 = max(i - x, 0)

r2_1 = min(i + x, n - 1)

c1_1 = max(j - x + 1, 0)

c2_1 = min(j + x, m - 1)

r1_2 = max(i - x + 1, 0)

r2_2 = min(i + x - 1, n - 1)

c1_2 = max(j - x, 0)

c2_2 = min(j + x + 1, m - 1)

# 查询两个区域的大值

max1 = seg_tree.query(r1_1, r2_1, c1_1, c2_1)

max2 = seg_tree.query(r1_2, r2_2, c1_2, c2_2)

if max(max1, max2)

ans += 1

return ans

def main:

"""测试用例"""

matrix = [

[0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 2, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0]

]

result = count_local_maximums(matrix)

print(result)

if __name__ == "__main__":

main

C++竣工代码如下:

.

#include

#include

#include

#include

#include

using namespace std;

// 维ST表模板

template

class SparseTable {

private:

vector> st;

T (*op)(T, T);

public:

SparseTable {}

SparseTable(const vector& arr, T (*operation)(T, T)) : op(operation) {

int n = arr.size;

if (n == 0) return;

int k = 0;

while ((1

st.resize(k, vector(n));

// 开动化0层

for (int i = 0; i

st[0][i] = arr[i];

}

// 构建ST表

for (int i = 1; i

int len = 1

int half = len >> 1;

for (int j = 0; j + len

st[i][j] = op(st[i-1][j], st[i-1][j + half]);

}

}

}

// 查询闭区间 [l, r]

T query(int l, int r) const {

if (l > r) {

// 复返个小值

if constexpr (is_same::value) {

return INT_MIN;

}

return T;

}

int length = r - l + 1;

int k = 0;

while ((1

return op(st[k][l], st[k][r - (1

}

};

// 线段树类

class SegmentTree {

private:

vector>& matrix;

int n, m;

vector> tree;

int size;

// 并两个数组,按列取大值

vector mergeColumns(const vector& left, const vector& right) {

vector result(m);

for (int i = 0; i

result[i] = max(left[i], right[i]);

}

return result;

}

void build(int node, int l, int r) {

if (l == r) {

// 叶子节点:径直使用该行的ST表

tree[node] = SparseTable(matrix[l], [](int a, int b) { return max(a, b); });

return;

}

int mid = (l + r) / 2;

build(node * 2, l, mid);

build(node * 2 + 1, mid + 1, r);

// 并附近子树:对每列取大值

vector merged(m);

for (int i = 0; i

merged[i] = max(tree[node * 2].query(i, i), tree[node * 2 + 1].query(i, i));

}

tree[node] = SparseTable(merged, [](int a, int b) { return max(a, b); });

}

int queryRec(int node, int l, int r, int r1, int r2, int c1, int c2) const {

if (r1

return tree[node].query(c1, c2);

}

int mid = (l + r) / 2;

if (r2

return queryRec(node * 2, l, mid, r1, r2, c1, c2);

}

if (r1 > mid) {

return queryRec(node * 2 + 1, mid + 1, r, r1, r2, c1, c2);

}

int left_val = queryRec(node * 2, l, mid, r1, r2, c1, c2);

int right_val = queryRec(node * 2 + 1, mid + 1, r, r1, r2, c1, c2);

return max(left_val, right_val);

}

public:

SegmentTree(vector>& mat) : matrix(mat) {

n = matrix.size;

m = matrix[0].size;

// 计较线段树大小

size = 1;

while (size

tree.resize(size * 2);

build(1, 0, n - 1);

}

int query(int r1, int r2, int c1, int c2) const {

if (r1 > r2 手机号码:15222026333相关词条:管道保温     塑料管材生产线     锚索    玻璃棉毡    PVC管道管件粘结胶

1.本网站以及本平台支持关于《新广告法》实施的“极限词“用语属“违词”的规定陇南15.2钢绞线规格及参数,并在网站的各个栏目、产品主图、详情页等描述中规避“违禁词”。
2.本店欢迎所有用户指出有“违禁词”“广告法”出现的地方,并积极配合修改。
3.凡用户访问本网页,均表示默认详情页的描述,不支持任何以极限化“违禁词”“广告法”为借口理由投诉违反《新广告法》,以此来变相勒索商家索要赔偿的违法恶意行为。