矩阵中严格递增的单元格数

Posted 929code

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了矩阵中严格递增的单元格数相关的知识,希望对你有一定的参考价值。

给你一个下标从 1 开始、大小为 m x n 的整数矩阵 mat,你可以选择任一单元格作为 起始单元格
从起始单元格出发,你可以移动到同一行或同一列 中的任何其他单元格,但前提是目标单元格的值严格大于当前单元格的值
求能访问的最多单元格数

1. 动态规划(超时)

如果对每一个点进行递归搜索,时间复杂度会非常庞大
考虑使用动态规划减小时间复杂度
dp[i][j]表示以位置(i,j)为起点的最大路径单元格
最坏情况下每个元素都要横向纵向扫描一遍,时间复杂度为O(mn(m+n)),最后结果超时

假设dp[i][j]表示以位置(i,j)为终点的最大路径单元格
递归就变成了往前搜索,找更小的数,实质上跟上面没有区别
所以在方法二优化中,从小到大和从大到小的顺序没有影响

class Solution 
public:
    int m; int n;
    vector<vector<int>> dp;
    int maxIncreasingCells(vector<vector<int>>& mat) 
        //动态规划,记录每一个位置能访问的最大单元格
        m = mat.size(); n= mat[0].size();
        dp.resize(m,vector<int>(n));
        int res = 0;
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                res = max(res,dfs(mat,i,j));
        return res;

    
    int dfs(vector<vector<int>>& mat,int x,int y)
        if(dp[x][y]) return dp[x][y];
        dp[x][y] = 1;
        for(int i=0;i<n;i++) //遍历同一行
            if(mat[x][i]>mat[x][y]) dp[x][y] = max(dp[x][y] ,dfs(mat,x,i)+1);
        for(int i=0;i<m;i++) //遍历同一列
            if(mat[i][y]>mat[x][y]) dp[x][y]  = max(dp[x][y] ,dfs(mat,i,y)+1);
        return dp[x][y];
    
;

2. 动态规划优化

我们现在要想办法免去方法一的横纵向搜索过程
使时间复杂度优化到O(mn),必然要采取某种贪心思想
仔细观察方法一中的搜索过程,遍历同一行和同一列
是试图寻找同一行和同一列更大值的最大单元格数
我们可以直接记录更新记录该行和该列更大值的最大单元格数
这要求我们从大到小遍历所有值,并对行列最大值单元格进行更新
此时对应dp[i][j]表示以位置(i,j)为起点的最大路径单元格
搜索行列更大值,反过来就是从最大值从大到小更新记录

class Solution 
public:
    int maxIncreasingCells(vector<vector<int>> &mat) 
        int m = mat.size(), n = mat[0].size();
        vector<pair<int,int>> nums;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                nums.push_back(mat[i][j],i*n+j);
        sort(nums.begin(),nums.end());
        int res = 0;
        vector<int> row_max(m), col_max(n);
        //按值从大到小访问
        for(int cnt=nums.size()-1;cnt>=0;)
            vector<pair<int,int>> same;; // 存储所有相同值,避免视作更小值
            int pre = nums[cnt].first;
            while(cnt>=0&&nums[cnt].first==pre)
                auto &[val,index] = nums[cnt]; cnt--;
                pre = val;//记录上一个值
                int i = index/n; int j = index%n;
                int updateval = max(row_max[i], col_max[j])+1; //获取最新的最大单元格数
                same.push_back(updateval,index);
                res = max(res,updateval);
            
            for (int k = 0; k < same.size(); k++) //遍历相同值,进行更新
                auto &[updateval, index] = same[k];
                int i = index/n; int j = index%n;
                row_max[i] = max(row_max[i], updateval); // 更新第 i 行的最大 f 值
                col_max[j] = max(col_max[j], updateval); // 更新第 j 列的最大 f 值
            
        
        return res;
    
;

同样我们也能从小到大遍历所有值
此时对应dp[i][j]表示以(i,j)为终点的最大单元格数,搜索行列更小值
反过来就是从最小值从小到大更新行列最大单元格

class Solution 
public:
    int maxIncreasingCells(vector<vector<int>> &mat) 
        map<int, vector<pair<int, int>>> g; //这里使用红黑树进行排序
        int m = mat.size(), n = mat[0].size();
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                g[mat[i][j]].emplace_back(i, j); // 相同元素放在同一组,统计位置,同时避免把相同值视为更大值,重复更新

        int ans = 0;
        vector<int> row_max(m), col_max(n);
        //按值从小到大访问
        for (auto &[_, pos]: g) 
            vector<int> mx; // 先把最大值算出来,再更新 row_max 和 col_max
            for (auto &[i, j]: pos) //获得当前值的所有位置
                mx.push_back(max(row_max[i], col_max[j]) + 1); //这里暂存不直接进行更新,避免重复值多次更新
                ans = max(ans, mx.back());
            
            for (int k = 0; k < pos.size(); k++) //遍历所有位置,进行更新
                auto &[i, j] = pos[k];
                row_max[i] = max(row_max[i], mx[k]); // 更新第 i 行的最大 f 值
                col_max[j] = max(col_max[j], mx[k]); // 更新第 j 列的最大 f 值
            
        
        return ans;
    
;

滑块值更改时快速更新表格中的单元格数

【中文标题】滑块值更改时快速更新表格中的单元格数【英文标题】:Swift Update number of cells in table when slider value changes 【发布时间】:2020-04-08 12:30:47 【问题描述】:

我想在移动滑块时更新表格中的单元格数。我真的不知道该怎么做,也没有找到任何适合我的情况。有方法吗?

提前谢谢你

【问题讨论】:

【参考方案1】:

是的,您要做的是在滑块的值发生变化时调用tableView.realodData()

有几种方法可以捕获滑块更改事件,但通常使用UISlider's 值更改操作。

    override func viewDidLoad() 
        super.viewDidLoad()
        slider.addTarget(self, action: #selector(sliderValueChanged(_:)), for: .valueChanged)
    

    @objc func sliderValueChanged(_ sender: UISlider) 
        updateTableViewNumberOfRows() // update number of rows in this function
                                      // or write the code here, it's up to you
        tableView.reloadData()
    

【讨论】:

以上是关于矩阵中严格递增的单元格数的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 中的 UICollectionViewFlowLayout - 每个部分中的动态单元格数

使用 Parse 获取 UITableView 中的单元格数

UICollectionView 和每列的单元格数

329. 矩阵中的最长递增路径

#yyds干货盘点# 面试必刷TOP101:矩阵最长递增路径

在矩阵中找到最长的递增路径