-
C++ 1s的代码,python 5s都跑不动,达不到C++ 1s的分,5000*5000个点算一下距离就4s了,现在的瓶颈是python而不是算法了。
-
😀前言 在编程问题中,处理字符串是一个常见的挑战,其中有一个经典问题就是寻找字符串中最长不含重复字符的子字符串。该问题的目的是在给定的字符串中,找到一个没有重复字符的子字符串,并返回其长度。🥰最长不含重复字符的子字符串牛客网😊题目描述我们需要解决的是:给定一个只包含小写字母(a~z)的字符串,找出其最长的不含重复字符的子字符串的长度。例如,对于输入字符串 arabcacfr,其中最长的不含重复字符的子字符串是 acfr,其长度为4。😉解题思路解决这个问题最简单的思路是使用暴力法:遍历字符串的所有子字符串,检查每个子字符串是否包含重复字符,记录没有重复字符的最长子字符串的长度。然而,这种方法效率较低,尤其是在处理大规模字符串时,时间复杂度可能会达到 O(n²),因此我们需要一种更高效的方案。高效的方法可以通过滑动窗口和哈希表来优化,我们只需线性遍历字符串一次即可解决问题,时间复杂度为 O(n)。下面的 Java 代码实现了这个思路。😁Java代码实现public int longestSubStringWithoutDuplication(String str) { int curLen = 0; // 当前不含重复字符的子字符串长度 int maxLen = 0; // 目前找到的最长子字符串长度 int[] preIndexs = new int[26]; // 记录字符上一次出现的位置 Arrays.fill(preIndexs, -1); // 初始化字符的上次出现位置为 -1 for (int curI = 0; curI < str.length(); curI++) { int c = str.charAt(curI) - 'a'; // 将字符映射到 0 ~ 25 的整数 int preI = preIndexs[c]; // 获取该字符上次出现的位置 if (preI == -1 || curI - preI > curLen) { // 如果字符第一次出现或者在当前子字符串之外,更新当前长度 curLen++; } else { // 如果字符在当前子字符串内出现过,更新最长长度,并从重复字符之后开始新子字符串 maxLen = Math.max(maxLen, curLen); curLen = curI - preI; } preIndexs[c] = curI; // 更新字符上次出现的位置 } maxLen = Math.max(maxLen, curLen); // 确保结束时记录到最长长度 return maxLen; }代码详解变量定义:curLen: 当前不含重复字符的子字符串长度。maxLen: 记录到目前为止,最长的不含重复字符子字符串的长度。preIndexs: 一个大小为26的数组,用来存储每个字符上次出现在字符串中的位置。由于字符串只包含a~z的字符,因此数组长度为26,preIndexs[i]对应第i个字母(a对应0,b对应1,以此类推)。初始化:将 preIndexs 数组的所有元素初始化为 -1,表示每个字符一开始都没有出现过。遍历字符串:遍历字符串的每个字符,获取其在 preIndexs 中记录的上一次出现的位置 preI。如果该字符第一次出现,或者它的上一次出现位置在当前子字符串之外(即 curI - preI > curLen),说明当前字符没有重复,当前子字符串的长度 curLen 增加1。如果该字符在当前子字符串内出现过(即 curI - preI <= curLen),则更新 maxLen,并将当前子字符串重新设置为从重复字符的下一个位置开始,长度为 curI - preI。更新位置:每次遍历字符时,将其在 preIndexs 中的位置更新为当前下标。返回结果:遍历完字符串后,再次更新 maxLen,确保返回值是最终的最长子字符串长度。解题思路总结这个算法的核心思想是用滑动窗口的方法动态维护一个不含重复字符的子字符串,并通过记录每个字符的上一次出现位置,避免了重复字符的出现。这样我们就能在一次遍历中找到最长的不含重复字符的子字符串,时间复杂度为 O(n),空间复杂度为 O(1)。💝算法复杂度分析时间复杂度:每个字符只会被访问两次(一次是进入窗口,一次是离开窗口),因此时间复杂度为 O(n),其中 n 是字符串的长度。空间复杂度:由于只需要一个长度为 26 的数组来存储字符出现的位置,空间复杂度为 O(1)。💖实际应用场景这种问题在实际开发中非常常见。例如:在文本处理系统中,我们可能需要查找一段不含重复字符的文本片段,以进行进一步的分析。在数据分析中,类似的思路可以用来寻找交易记录中的最长不重复行为序列。在爬虫等系统中,处理不同网页路径的去重问题时,字符串处理的高效算法也至关重要。😄总结求解最长不含重复字符的子字符串的问题,关键在于使用滑动窗口技术和哈希表来跟踪字符的最近出现位置,避免重复字符的出现,从而实现高效的解决方案。通过一次遍历,我们能够找到字符串中最长的不含重复字符的子字符串,并返回其长度。这种方法不仅减少了时间复杂度到 O(n),而且代码结构简洁,易于理解和实现。滑动窗口的思想广泛应用于各种字符串处理问题中,不仅限于这道题目,还可以拓展到其他场景。在实际应用中,处理字符串、文本或序列中的重复字符问题非常常见,无论是数据清理、爬虫去重还是用户行为分析,掌握这类高效的算法对于开发和优化系统具有重要意义。通过这道题,我们也可以更好地理解如何通过空间换时间的技巧来优化算法的性能,并学会利用数组或哈希表等工具来记录状态信息,使得问题可以在线性时间内高效解决。
-
看着评价指标计算还挺复杂的,请问是否提供评价指标计算的代码?谢谢
-
文档中的样例数据,图G里面有两个1,下面两个子图中都是1个1,如何确定子图里的那个1是图G的两个1中的哪个呢?根据顺序来判断吗?
-
第十一期所谓步骤3和4移动方向的改变,具体指什么?例如从p1到p2,对于步骤3,从p1移动到锚点的方向和之前移动到p1的方向不一致即视为方向改变?或者从p1移动到锚点的方向与从锚点移动到p2的方向不一致即视为方向改变?
-
请教一下反馈信息的runtime error和execution time exceeded的区别是啥
-
样例输入的数据出现了在输入的node中不存在的数值。比如:在主图中:大致对应的图如下边图所示(默认把最后一个1改为了5):node中并没有5。下面的2个子图:对应的画出来的图如下所示(默认把4改为了3):希望有人可以解释一下上面的数据不一致的原因,谢谢!
-
missing entry file是什么意思?
-
如题,还是说只能使用单核计算?
-
要实现点云的 SHOT (Signature of Histograms of OrienTations) 描述子,涉及到一些关键步骤,包括法线估计、参考帧计算、局部几何特征(例如,主成分分析)、直方图构建等。由于这个过程相对复杂,这里给出了一个简化版本的实现代码。这段代码假设你已经安装了 PCL 库,并能够加载 PCL 点云格式的数据。主要步骤法线估计参考帧计算计算SHOT描述子代码实现#include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/features/normal_3d.h> #include <pcl/kdtree/kdtree_flann.h> #include <iostream> #include <vector> #include <cmath> using namespace std; using PointT = pcl::PointXYZ; /** * @brief 计算点云中每个点的法线 */ void computeNormals(const pcl::PointCloud<PointT>::Ptr &cloud, pcl::PointCloud<pcl::Normal>::Ptr &normals, float radius) { pcl::NormalEstimation<PointT, pcl::Normal> ne; ne.setInputCloud(cloud); pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>()); ne.setSearchMethod(tree); ne.setRadiusSearch(radius); ne.compute(*normals); } /** * @brief 计算参考帧 */ void computeReferenceFrames(const pcl::PointCloud<PointT>::Ptr &cloud, const pcl::PointCloud<pcl::Normal>::Ptr &normals, vector<Eigen::Matrix3f> &reference_frames, float radius) { // 初始化KdTree pcl::search::KdTree<PointT> kdtree; kdtree.setInputCloud(cloud); for (size_t i = 0; i < cloud->points.size(); ++i) { vector<int> pointIdxRadiusSearch; vector<float> pointRadiusSquaredDistance; if (kdtree.radiusSearch(cloud->points[i], radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0) { Eigen::Vector3f normal = normals->points[i].getNormalVector3fMap(); Eigen::Vector3f u, v; // 创建正交基 if (fabs(normal(0)) > fabs(normal(1))) { float invNorm = 1.0f / sqrt(normal(0) * normal(0) + normal(2) * normal(2)); u = Eigen::Vector3f(-normal(2) * invNorm, 0.0f, normal(0) * invNorm); } else { float invNorm = 1.0f / sqrt(normal(1) * normal(1) + normal(2) * normal(2)); u = Eigen::Vector3f(0.0f, normal(2) * invNorm, -normal(1) * invNorm); } v = normal.cross(u); // 构建参考系矩阵 Eigen::Matrix3f reference_frame; reference_frame.col(0) = u; reference_frame.col(1) = v; reference_frame.col(2) = normal; reference_frames.push_back(reference_frame); } } } /** * @brief 计算SHOT描述子 */ void computeSHOTDescriptors(const pcl::PointCloud<PointT>::Ptr &cloud, const pcl::PointCloud<pcl::Normal>::Ptr &normals, const vector<Eigen::Matrix3f> &reference_frames, vector<vector<float>> &descriptors, float radius, int bins) { // 初始化KdTree pcl::search::KdTree<PointT> kdtree; kdtree.setInputCloud(cloud); for (size_t i = 0; i < cloud->points.size(); ++i) { vector<int> pointIdxRadiusSearch; vector<float> pointRadiusSquaredDistance; if (kdtree.radiusSearch(cloud->points[i], radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0) { // 初始化直方图 vector<float> descriptor(bins, 0); for (size_t j = 0; j < pointIdxRadiusSearch.size(); ++j) { if (pointIdxRadiusSearch[j] == i) continue; Eigen::Vector3f point_diff = cloud->points[pointIdxRadiusSearch[j]].getVector3fMap() - cloud->points[i].getVector3fMap(); float dist = point_diff.norm(); if (dist > radius) continue; Eigen::Vector3f local_point = reference_frames[i].transpose() * point_diff; float elevation = atan2(local_point(2), sqrt(local_point(0) * local_point(0) + local_point(1) * local_point(1))); float azimuth = atan2(local_point(1), local_point(0)); float radial_dist = dist; int elevation_bin = static_cast<int>((elevation + M_PI_2) * bins / M_PI); int azimuth_bin = static_cast<int>((azimuth + M_PI) * bins / (2 * M_PI)); int distance_bin = static_cast<int>(radial_dist * bins / radius); if (elevation_bin >= 0 && elevation_bin < bins && azimuth_bin >= 0 && azimuth_bin < bins && distance_bin >= 0 && distance_bin < bins) { descriptor[elevation_bin]++; descriptor[azimuth_bin]++; descriptor[distance_bin]++; } } // 归一化直方图 float sum = accumulate(descriptor.begin(), descriptor.end(), 0.0f); for (auto &value : descriptor) { value /= sum; } descriptors.push_back(descriptor); } } } int main(int argc, char **argv) { pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>()); if (pcl::io::loadPCDFile<PointT>("path_to_your_pcd_file.pcd", *cloud) == -1) { PCL_ERROR("Couldn't read the PCD file\n"); return -1; } pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>()); computeNormals(cloud, normals, 0.05f); // 半径根据需要调整 vector<Eigen::Matrix3f> reference_frames; computeReferenceFrames(cloud, normals, reference_frames, 0.05f); // 半径根据需要调整 vector<vector<float>> descriptors; computeSHOTDescriptors(cloud, normals, reference_frames, descriptors, 0.05f, 10); // 半径和bin数根据需要调整 cout << "Computed SHOT descriptors for " << descriptors.size() << " points." << endl; return 0; }解释computeNormals: 使用 NormalEstimation 计算每个点的法线。computeReferenceFrames: 为每个点计算参考帧。参考帧用于将邻域点转换到局部坐标系。computeSHOTDescriptors: 基于参考帧和邻域点计算SHOT描述子。这部分计算了直方图并进行了归一化。注意事项以上代码是简化版,实际应用可能还需考虑更多细节,例如噪声处理、优化计算速度等。使用适当的半径参数非常重要,它会直接影响法线估计和描述子的质量。BINS 的选择也很重要,通常情况下,更多的BINS 会提供更精确的描述,但也会增加计算量。
-
编写一个用于描述 "Hill48屈服模型 等向强化 非线性硬化" 的Abaqus本构子程序(UMAT或VUMAT)涉及复杂的理论推导和数值实现。下面我们将详细介绍这个过程,包括牛顿迭代的构建,应力应变更新等。1. Hill48 屈服准则Hill48屈服准则是一种各向异性屈服准则,用于描述各向异性材料的屈服行为。其数学形式为:[ f(\sigma) = F(\sigma_{22} - \sigma_{33})^2 + G(\sigma_{33} - \sigma_{11})^2 + H(\sigma_{11} - \sigma_{22})^2 + 2L\sigma_{23}^2 + 2M\sigma_{31}^2 + 2N\sigma_{12}^2 = 1 ]其中, (F, G, H, L, M, N) 是各向异性系数,通过实验数据拟合得到。2. 等向强化与非线性硬化等向强化假设材料在塑性变形过程中,其屈服面保持形状不变但会均匀扩展。因此,屈服函数可以写成:[ f(\sigma - \alpha) = \sigma_{eq} - \sigma_y = 0 ]其中:(\sigma_{eq}) 是等效应力,根据Hill48准则计算得出。(\alpha) 是背应力张量。(\sigma_y) 是屈服应力,随着塑性应变累积而变化。非线性硬化通常采用一些经验公式,如Voce硬化模型:[ \sigma_y (\bar{\varepsilon_p}) = \sigma_{y0} + Q (1 - e^{-b \bar{\varepsilon_p}}) ]其中,(\sigma_{y0}) 是初始屈服应力,(Q) 和 (b) 是硬化参数,(\bar{\varepsilon_p}) 是累积塑性应变。3. 应力更新与牛顿迭代法在有限元分析中,需要进行应力更新,这通常通过增量形态的应力-应变关系来实现。在实现此类算法时,使用牛顿-拉夫森迭代是常见的选择。牛顿迭代法目标是找到塑性屈服函数 (f(\sigma)) 满足以下方程:[ f(\sigma^{n+1}) = 0 ]对于增量步长 (\Delta t),假定初始猜测 (\sigma^{n+1}_{(0)}),其更新格式为:[ \sigma^{n+1}{(k+1)} = \sigma^{n+1}{(k)} - \left[ \frac{\partial f}{\partial \sigma} \right]^{-1} f(\sigma^{n+1}_{(k)}) ]这里需要计算雅可比矩阵 (\mathbf{J} = \frac{\partial f}{\partial \sigma})。4. UMAT伪代码实现以下是一个简化版的UMAT伪代码,实现了上述理论推导过程:subroutine umat(stress, statev, ddsdde, sse, spd, scd, rpl, ddsddt, drplde, drpldt, stran, dstran, time, dtime, temp, dtemp, predef, dpred, cmname, ndi, nshr, ntens, nstatv, props, nprops, coords, drot, pnewdt, celent, dfgrd0, dfgrd1, noel, npt, layer, kspt, kstep, kinc) implicit none ! Define parameters integer :: ndi, nshr, ntens, nstatv, nprops integer :: noel, npt, layer, kspt, kstep, kinc real(8) :: stress(ntens), statev(nstatv) real(8) :: ddsdde(ntens,ntens), sse, spd, scd, rpl real(8) :: ddsddt(ntens), drplde(ntens), drpldt real(8) :: stran(ntens), dstran(ntens), time(2) real(8) :: dtime, temp, dtemp, predef, dpred real(8) :: props(nprops), coords(3), drot(3,3) real(8) :: pnewdt, celent, dfgrd0(3,3), dfgrd1(3,3) character(len=*) :: cmname ! Material properties and hardening parameters real(8) :: E, nu, sigma_y0, Q, b real(8) :: F, G, H, L, M, N real(8) :: dep(ntens), ep_plastic, sigma_eq, delta_gamma real(8) :: alpha(ntens), back_stress(ntens) integer :: i, j parameter (E=props(1), nu=props(2), sigma_y0=props(3)) parameter (Q=props(4), b=props(5)) parameter (F=props(6), G=props(7), H=props(8), L=props(9), M=props(10), N=props(11)) ! Initialize variables ep_plastic = statev(1) do i = 1, ntens alpha(i) = statev(i + 1) end do ! Trial elastic predictor dep = dstran - dtime * back_stress / E stress = stress + E * dep ! Check yield condition using Hill48 criterion sigma_eq = sqrt(F * (stress(2) - stress(3))**2 + G * (stress(3) - stress(1))**2 + H * (stress(1) - stress(2))**2 + 2 * L * stress(4)**2 + 2 * M * stress(5)**2 + 2 * N * stress(6)**2) if (sigma_eq > sigma_y0 + Q * (1 - exp(-b * ep_plastic))) then ! Plastic correction using Newton-Raphson iterations delta_gamma = 0.0 do while (abs(f(sigma_eq)) > tolerance) delta_gamma = delta_gamma - f(sigma_eq) / df_dsigma(sigma_eq) ! Update stresses and plastic strain increment stress = stress - delta_gamma * ddsdde ep_plastic = ep_plastic + delta_gamma sigma_eq = sqrt(F * (stress(2) - stress(3))**2 + G * (stress(3) - stress(1))**2 + H * (stress(1) - stress(2))**2 + 2 * L * stress(4)**2 + 2 * M * stress(5)**2 + 2 * N * stress(6)**2) end do end if ! Update state variables statev(1) = ep_plastic do i = 1, ntens statev(i + 1) = alpha(i) end do end subroutine umat5. 详细推导过程应力更新基于弹性预测器:[ \boldsymbol{\sigma}^{\text{trial}} = \boldsymbol{\sigma}^n + \mathbf{C} : (\boldsymbol{\varepsilon}^{n+1} - \boldsymbol{\varepsilon}^n) ]其中 (\mathbf{C}) 是弹性模量张量。判断是否屈服计算等效应力 (\sigma_{eq}) 并判断:[ \sigma_{eq} > \sigma_y(\bar{\varepsilon_p}) ]塑性修正若屈服,则进行塑性修正,使用Newton-Raphson迭代求解塑性增量 (\Delta \gamma):[ \boldsymbol{\sigma}^{n+1} = \boldsymbol{\sigma}^{\text{trial}} - \Delta \gamma \mathbf{C} : \mathbf{n} ]更新塑性应变:[ \bar{\varepsilon_p}^{n+1} = \bar{\varepsilon_p}^n + \Delta \gamma ]总结以上是针对 "Hill48屈服模型 等向强化 非线性硬化" 的Abaqus本构子程序(UMAT)的理论推导过程及其简化实现。实际实现中,还需要更多细节处理,包括梯度计算、收敛性检查等。
-
直接贴代码import { cryptoFramework } from '@kit.CryptoArchitectureKit';import { buffer, util } from '@kit.ArkTS';export class CryptoUtil { private key: cryptoFramework.SymKey; private iv: cryptoFramework.IvParamsSpec; private cipher: cryptoFramework.Cipher; private decoder: cryptoFramework.Cipher; private static instance: CryptoUtil; private constructor(key: string, iv: string) { this.key = this.genSymKeyByData(key); this.iv = this.genIvParamsSpec(iv); this.cipher = cryptoFramework.createCipher('3DES192|CBC|PKCS7'); this.decoder = cryptoFramework.createCipher('3DES192|CBC|PKCS7'); } public static getInstance(key: string, iv: string): CryptoUtil { if (!CryptoUtil.instance) { CryptoUtil.instance = new CryptoUtil(key, iv) } return CryptoUtil.instance; } // 加密消息 public encryptMessageWithDESCBC(message: string): string { if(message.length==0){ return ""; } let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }; this.cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, this.key, this.iv); let encryptData = this.cipher.doFinalSync(plainText); let base = new util.Base64Helper(); return base.encodeToStringSync(encryptData.data); } // 解密消息 public decryptMessageWithDESCBC(message:string|undefined): string { if(message==undefined|| message.length==0){ return ""; } this.decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, this.key, this.iv); let base = new util.Base64Helper(); let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(message) }; let decryptData = this.decoder.doFinalSync(plainText); if (decryptData.data.toString() === decryptData.data.toString()) { let textDecoder = util.TextDecoder.create('utf-8'); return textDecoder.decodeWithStream(decryptData.data); } else { console.error('decrypt failed'); return ""; } } private genSymKeyByData(key: string) { key = key.substring(0, 8); let keyData = new Uint8Array(24); keyData.set(new util.TextEncoder().encodeInto(key)) let symKeyBlob: cryptoFramework.DataBlob = { data: keyData }; let symGenerator = cryptoFramework.createSymKeyGenerator('3DES192'); let symKey = symGenerator.convertKeySync(symKeyBlob); return symKey; } private genIvParamsSpec(iv: string): cryptoFramework.IvParamsSpec { iv = iv.substring(0, 8); let dataIv = new Uint8Array(24); dataIv.set(new util.TextEncoder().encodeInto(iv)) let ivBlob: cryptoFramework.DataBlob = { data: dataIv }; let ivParamsSpec: cryptoFramework.IvParamsSpec = { algName: 'IvParamsSpec', iv: ivBlob }; return ivParamsSpec; }}调用方式:调用效果:
-
LC54螺旋矩阵I给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]class Solution { public: vector<int> spiralOrder(vector<vector<int>>& matrix) { if(matrix.empty())return{}; int r=matrix[0].size()-1; int b=matrix.size()-1; int l=0,t=0; vector<int>res; while(1){ for(int i=l;i<=r;i++)res.push_back(matrix[t][i]);//左到右 if(++t>b)break; for(int i=t;i<=b;i++)res.push_back(matrix[i][r]);//上到下 if(--r<l)break; for(int i=r;i>=l;i--)res.push_back(matrix[b][i]);//右到左 if(--b<t)break; for(int i=b;i>=t;i--)res.push_back(matrix[i][l]);//下到上 if(++l>r)break; } return res; } };
-
LC59螺旋矩阵II给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。示例:输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]解法一:class Solution { public: vector<vector<int>> generateMatrix(int n) { vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组 int startx = 0, starty = 0; // 定义每循环一个圈的起始位置 int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理 int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2) int count = 1; // 用来给矩阵中每一个空格赋值 int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位 int i,j; while (loop --) { i = startx; j = starty; // 下面开始的四个for就是模拟转了一圈 // 模拟填充上行从左到右(左闭右开) for (j; j < n - offset; j++) { res[i][j] = count++; } // 模拟填充右列从上到下(左闭右开) for (i; i < n - offset; i++) { res[i][j] = count++; } // 模拟填充下行从右到左(左闭右开) for (; j > starty; j--) { res[i][j] = count++; } // 模拟填充左列从下到上(左闭右开) for (; i > startx; i--) { res[i][j] = count++; } // 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1) startx++; starty++; // offset 控制每一圈里每一条边遍历的长度 offset += 1; } // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值 if (n % 2) { res[mid][mid] = count; } return res; } };解法二:cpp解法class Solution { public: int left = 0, right = n-1, top = 0, bottom = n-1; int count = 1, target = n * n; vector<vector<int>> res(n, vector<int>(n, 0)); //for循环中变量定义成i或j的细节:按照通常的思维,i代表行,j代表列 //这样,就可以很容易区分出来变化的量应该放在[][]的第一个还是第二个 //对于变量的边界怎么定义: //从左向右填充:填充的列肯定在[left,right]区间 //从上向下填充:填充的行肯定在[top,bottom]区间 //从右向左填充:填充的列肯定在[right,left]区间 //从下向上填充:填充的行肯定在[bootom,top]区间 //通过上面的总结会发现边界的起始和结束与方向是对应的 while(count <= target){ //从左到右填充,相当于缩小上边界 for(int j = left; j <= right; j++) res[top][j] = count++; //缩小上边界 top++; //从上向下填充,相当于缩小右边界 for(int i = top; i <=bottom; i++) res[i][right] = count++; //缩小右边界 right--; //从右向左填充,相当于缩小下边界 for(int j = right; j >= left; j--) res[bottom][j] = count++; //缩小下边界 bottom--; //从下向上填充,相当于缩小左边界 for(int i = bottom; i >= top; i--) res[i][left] = count++; //缩小左边界 left++; } return res; }php解法class Solution{ public function generateMatrix($n): array{ $left = 0;$right = $n-1; $top = 0; $bottom = $n-1; $count = 1;$target = $n * $n; $res=array_fill(0,$n,array_fill(0,$n,0)); while ($count <= $target) { // 从左到右填充,相当于缩小上边界 for ($j = $left; $j <= $right; $j++) { $res[$top][$j] = $count++; } // 缩小上边界 $top++; // 从上向下填充,相当于缩小右边界 for ($i = $top; $i <= $bottom; $i++) { $res[$i][$right] = $count++; } // 缩小右边界 $right--; // 从右向左填充,相当于缩小下边界 for ($j = $right; $j >= $left; $j--) { $res[$bottom][$j] = $count++; } // 缩小下边界 $bottom--; // 从下向上填充,相当于缩小左边界 for ($i = $bottom; $i >= $top; $i--) { $res[$i][$left] = $count++; } // 缩小左边界 $left++; } return $res; } }public class Solution{ public int[][] generateMatrix(int n){ int left = 0, right = n-1, top = 0, bottom = n-1; int count = 1, target = n * n; int[][] res=new int[n][n]; //for循环中变量定义成i或j的细节:按照通常的思维,i代表行,j代表列 //这样,就可以很容易区分出来变化的量应该放在[][]的第一个还是第二个 //对于变量的边界怎么定义: //从左向右填充:填充的列肯定在[left,right]区间 //从上向下填充:填充的行肯定在[top,bottom]区间 //从右向左填充:填充的列肯定在[right,left]区间 //从下向上填充:填充的行肯定在[bootom,top]区间 //通过上面的总结会发现边界的起始和结束与方向是对应的 while(count <= target){ //从左到右填充,相当于缩小上边界 for(int j = left; j <= right; j++) res[top][j] = count++; //缩小上边界 top++; //从上向下填充,相当于缩小右边界 for(int i = top; i <=bottom; i++) res[i][right] = count++; //缩小右边界 right--; //从右向左填充,相当于缩小下边界 for(int j = right; j >= left; j--) res[bottom][j] = count++; //缩小下边界 bottom--; //从下向上填充,相当于缩小左边界 for(int i = bottom; i >= top; i--) res[i][left] = count++; //缩小左边界 left++; } return res; } }
上滑加载中
推荐直播
-
TinyEngine低代码引擎系列.第1讲——低代码浪潮之下,带你走进TinyEngine
2024/11/11 周一 16:00-18:00
李老师 高级前端开发工程师
低代码浪潮之下,带你走进TinyEngine。李旭宏老师将从低代码的发展趋势、TinyEngine的项目介绍,三方物料组件的使用、跨技术栈的使用、源码生成能力的差异性对比等多个方面带大家对TinyEngine低代码引擎有一个更清晰的认知和了解。
即将直播 -
0代码智能构建AI Agent——华为云AI原生应用引擎的架构与实践
2024/11/13 周三 16:30-18:00
苏秦 华为云aPaaS DTSE技术布道师
大模型及生成式AI对应用和软件产业带来了哪些影响?从企业场景及应用开发视角,面向AI原生应用需要什么样的工具及平台能力?企业要如何选好、用好、管好大模型,使能AI原生应用快速创新?本期直播,华为云aPaaS DTSE技术布道师苏秦将基于华为云自身实践出发,深入浅出地介绍华为云AI原生应用引擎,通过分钟级智能生成Agent应用的方式帮助企业完成从传统应用到智能应用的竞争力转型,使能千行万业智能应用创新。
去报名
热门标签