74. Search a 2D Matrix

本文介绍了一种高效的二维矩阵搜索算法,适用于每一行从左到右递增排列且每行首元素大于前一行尾元素的矩阵。通过二分查找法实现对目标值的有效定位。

Search a 2D Matrix

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the previous row.

For example,

Consider the following matrix:

[
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]

Given target = 3, return true.

解析

根据题意,如果把二维数组拉直,看成一列的话,很明显这是一个递增的数列。则很容易想到二分查找法。
同时,根据某个值所在的序号(index),易计算其所在行和列。

  • 行号=index/collength;
  • 列号=index%collength;

代码

bool searchMatrix(int** matrix, int matrixRowSize, int matrixColSize, int target) {
    //二分查找
    int left=0;
    int right = matrixRowSize*matrixColSize-1;
    while(left<=right){
        int mid = (left+right)/2;
        int row = mid/matrixColSize;
        int col = mid%matrixColSize;
        if(matrix[row][col]==target){
            return true;
        }
        else if(matrix[row][col]>target){
            right=mid-1;
        }
        else{
            left=mid+1;
        }
    }
    return false;
}

时间复杂度为:O(log(m+n))

在COMSOL中遇到“Failed to compute the matrix factorization in the eigensolver”(特征值求解器矩阵分解失败)、“Try to search for eigenvalues around a different shift value”(尝试围绕不同的位移值搜索特征值)及“Out of memory during assembly”(组装过程中内存不足)等问题时,通常与特征值求解器的配置、网格规模或物理场设置相关。以下是可能的原因及解决方法: --- ### **1. 特征值求解器矩阵分解失败** - **原因**: 特征值求解器(如ARPACK、SLEPc)在计算矩阵特征值时,若矩阵条件数过大或位移值(shift)选择不当,可能导致分解失败。 - **解决方法**: - **调整位移值(Shift)**: 在特征值求解器设置中指定更合理的位移值(接近预期特征值): ```matlab model.study("std1").feature("eig").set("shift", 1e6); % 设置位移值为1e6(根据问题调整) ``` - **启用谱变换**: 对于对称问题,使用“位移-反转”变换改善矩阵条件数: ```matlab model.study("std1").feature("eig").set("transform", "shiftinvert"); % 启用位移反转变换 ``` - **减少求解特征值数量**: 降低求解的特征值数量(`neigs`)以简化问题: ```matlab model.study("std1").feature("eig").set("neigs", 10); % 仅求解前10个特征值 ``` --- ### **2. 内存不足(Assembly阶段)** - **原因**: 矩阵组装阶段内存不足通常由以下情况引起: - 网格规模过大(单元/自由度数过多)。 - 物理场耦合导致矩阵稠密(如完全耦合的多物理场)。 - 直接求解器(如MUMPS)用于大规模问题。 - **解决方法**: - **优化网格**: - 减少全局网格密度,仅在关键区域加密。 - 使用扫掠网格(Swept Mesh)或边界层网格减少自由度。 - **改用迭代求解器**: 在特征值求解器中切换为迭代法(如ARPACK): ```matlab model.study("std1").feature("eig").set("eigmethod", "eigs"); % 使用迭代特征值求解器 ``` - **启用稀疏矩阵存储**: 确保矩阵以稀疏格式存储(默认启用,但需检查): ```matlab model.component("comp1").physics("your_physics").prop("ShapeProperty").set("shapefunctiontype", "discontinuous"); % 必要时使用不连续函数减少带宽 ``` - **分布式计算**: 在COMSOL Server或集群上启用分布式矩阵组装和求解。 --- ### **3. 其他调试建议** 1. **检查物理场一致性**: - 确保所有材料参数、边界条件无冲突(如零刚度或负密度)。 - 对于结构力学问题,检查是否遗漏了约束(导致刚体位移)。 2. **简化测试**: - 先求解小规模问题(如2D简化模型)验证设置。 - 逐步增加物理场耦合,定位问题来源。 3. **监控求解器日志**: - 在COMSOL中启用详细日志(`Preferences > Logs > Verbose`),观察矩阵组装和分解的详细信息。 --- ### **示例代码(COMSOL API)** ```matlab % 设置特征值求解器参数 model.study("std1").feature("eig").set("eigmethod", "eigs"); % 迭代求解器 model.study("std1").feature("eig").set("transform", "shiftinvert"); % 谱变换 model.study("std1").feature("eig").set("shift", 1e6); % 位移值 model.study("std1").feature("eig").set("neigs", 10); % 特征值数量 % 优化网格和求解器 model.component("comp1").mesh("mesh1").autoMeshSize(5); % 减少网格密度 model.sol("sol1").feature("e1").set("linsolver", "gmres"); % 线性求解器改为GMRES ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值