百题选手突破题单(2)

127 阅读2分钟

掘金更文挑战

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情


题外话

这个题单面向的是有一定题量的同学,需要同学们对算法的结构有个大致的了解。在更新这个题单的时候,我并不会很系统和全面的更新某一类内容,一是能力有限,二是分类一大,可能大家很难一口气做完并形成归纳。我会尽力将一些经常出现的,有代表性的相似题目放在一起。它们可能是有递进关系的题目,可能是模板统一的“板子题”。

念念不忘,必有回响。锲而不舍,金石可镂。

打印矩阵

对矩阵搜索的模拟问题,思路简单,套路固定,但不熟练容易多耗时间,想要突破就是个精益求精的过程。

模板:

推荐按题目方向模拟,简单好记

  1. 矩阵搜索:使用静态数组存储搜索方向。
  2. 控制边界:抽取公用函数

思路很简单,但关键要熟,举例来说,搜索到不合法的坐标应当转向是题目的关键,但这是一个很粗略的想法。

试着将自己的思维细化到:前进 => 不合法坐标 => 回退坐标,更换方向 => 前进,这种可以转化为伪代码的思路。

54. 螺旋矩阵 题为例。

class Solution {
    int[][] dir = new int[][]{
        {0, 1}, {1, 0}, {0, -1}, {-1, 0}
        };
    int m;
    int n;
    boolean[][] used;
​
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> ans = new ArrayList();
        m = matrix.length;
        if(m == 0) return ans;
        n = matrix[0].length;
        if(n == 0) return ans;
        used = new boolean[m][n];
        int dir_cnt = 0;
        
        // 横纵坐标
        int i = 0;
        int j = 0;
        
        int cnt = 0;
        
        while(cnt < m*n){
            ans.add(matrix[i][j]);
            cnt++;
            used[i][j] = true;
            //前进一格
            i += dir[dir_cnt][0];
            j += dir[dir_cnt][1];
            //如果所在位置不可合法,回退并转向
            if(!isValid(i, j)){
                i -= dir[dir_cnt][0];
                j -= dir[dir_cnt][1];
                dir_cnt = (dir_cnt + 1) % 4;
                i += dir[dir_cnt][0];
                j += dir[dir_cnt][1];
            }
        }
        return ans;
    }
    
    
    public boolean isValid(int i, int j){
        //此题合法逻辑,在矩阵内且未遍历过
        if(i < m && i >= 0 && j < n && j>= 0 && !used[i][j]){
            return true;
        }else{
            return false;
        }
    } 
}

题目链接

以下题目都可以按照改模板去写。

题目链接参考题解
54. 螺旋矩阵见上文
59. 螺旋矩阵 II参考
885. 螺旋矩阵 III参考
498. 对角线遍历参考