LintCode "Submatrix Sum"

本文介绍了一种优化算法,通过列累积求和并利用哈希映射定位矩阵中最小非零和的子矩阵区域。适用于解决特定维度下的矩阵搜索问题,通过巧妙的数学公式简化复杂度。

Naive solution is O(n^4). But on 1 certain dimension, naive O(n^2) can be O(n) by this well-known equation: sum[i..j] = sum[0..j] - sum[0..i]. And pls take care of several corner cases.

class Solution {
public:
    /**
     * @param matrix an integer matrix
     * @return the coordinate of the left-up and right-down number
     */
    vector<vector<int>> submatrixSum(vector<vector<int>>& m) {

        int h = m.size();
        if(!h) return {};
        int w = m[0].size();
        if(!w) return {};

        // Get accumulate sum by columns
        vector<vector<int>> cols(h, vector<int>(w, 0));        
        for(int i = 0; i < w; i ++)
        {
            unordered_map<int, int> rec; // sum-inx
            for(int j = 0; j < h; j ++)
            {
                if(m[j][i] == 0)
                {
                    return {{i, j},{i, j}};
                }

                cols[j][i] = (j ? cols[j - 1][i] : 0) + m[j][i];
                if (!cols[j][i])
                {
                    return {{0, i}, {j, i}};
                }
                else if(rec.find(cols[j][i]) != rec.end())
                {
                    return {{rec[cols[j][i]] + 1, i}, {j, i}};
                }
                rec[cols[j][i]] = j;
            }
        }

        //  horizontal case
        for(int i = 0; i < h; i ++)
        for(int j = i; j < h; j ++)
        {
            vector<int> hsum(w, 0);
            for(int x = 0; x < w; x ++)
            {
                int prev = ((i == 0) ? 0 : cols[i - 1][x]);
                hsum[x] = cols[j][x] - prev;
            }
            // 
            vector<int> asum(w, 0);
            unordered_map<int, int> rec; // sum-inx
            for(int x = 0; x < w; x ++)
            {
                int nsum = (x ? asum[x - 1] : 0) + hsum[x];
                if (!nsum)
                {
                    return {{i + 1, 0}, {j, x}};
                }
                else if(rec.find(nsum) != rec.end())
                {
                    return {{i, rec[nsum] + 1}, {j, x}};
                }
                rec[nsum] = x;
                asum[x] = nsum;
            }
        }

        return {};
    }
};
View Code

转载于:https://www.cnblogs.com/tonix/p/4831108.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值