4.14

54. 螺旋矩阵 - 力扣(LeetCode)

法一:偏移量法

问题分析

  1. 方向数组顺序错误
    • 原代码的方向数组为 dirs = {{1,0}, {0,-1}, {-1,0}, {0,1}},对应方向顺序为 下→左→上→右
    • 正确的螺旋遍历顺序应为 右→下→左→上,即方向数组应为 {{0,1}, {1,0}, {0,-1}, {-1,0}}
  2. 越界移动
    • 当检测到下一步越界时,会切换方向,但直接按新方向移动可能导致新的位置越界。
    • 例如:初始方向错误导致移动路径偏离,后续方向切换无法纠正,最终访问非法内存。
//越界代码
class Solution {
  public:
      vector<int> spiralOrder(vector<vector<int>>& matrix) {
          int m = matrix.size();
          int n = matrix[0].size();
          int dirs[4][2] ={{1 , 0} , {0 , -1} , {-1 , 0} , { 0 , 1}};//错误行
        //int dirs[4][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}}; 对应的才是右下左上
        //因为走的时候是x = x + 0(对应行) y = y + 1(对应列),而不是平时的xy轴
          vector<int> ans(m * n);

         int i = 0 , j = 0 , dir = 0;
         for (int k = 0 ; k < m * n; k++) {
            ans[k] = matrix[i][j];
            matrix[i][j] = INT_MAX;

            int x = i + dirs[dir][0];
            int y = j + dirs[dir][1]; 

            if(x < 0 || x >= m || y < 0 || y >= n || matrix[x][y] == INT_MAX){
              dir = (dir + 1) % 4;
            }

            i += dirs[dir][0];
            j += dirs[dir][1];
         }
         return ans;
      }
  };

法二:模拟

class Solution {
public:
 vector<int> spiralOrder(vector<vector<int>>& matrix) {
   int l = 0;
   int r = matrix[0].size() - 1; //列数
   int t = 0;  //top上边界
   int b = matrix.size() - 1; //bottom下边界
   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(l > --r) break;
       //右->左
       for (int i = r ; i >= l ; i --)  res.push_back(matrix[b][i]);
       //紧接着往上,收缩下边界,判断此时上下是否重合
       if(t > --b ) break;
       //下->上
       for (int i = b ; i >= t ; i --) res.push_back(matrix[i][l]);
       //紧接着往右,收缩左边界,判断此时左右是否重合
       if(++l > r ) break;
     }      
     return res;
 }
};

145. 二叉树的后序遍历 - 力扣(LeetCode)

迭代法:

class Solution {
  public:
      vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> res;
        if(!root)  return res;
        st.push(root);
        while(!st.empty()){
          TreeNode* node = st.top();
          st.pop();
          res.push_back(node->val);//中右左  翻转->  左右中
          if(node->left)  st.push(node->left);
          if(node->right)  st.push(node->right);
        }
        ranges::reverse(res);
          return res;
      }
  };

递归法:

class Solution {
  public:
      vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
          auto dfs = [&](this auto&& dfs , TreeNode* node)->void{
            if(!node)  return;
            dfs(node->left);
            dfs(node->right);
            res.push_back(node->val);
          };
          dfs(root);
          return res;
      }
  };

199. 二叉树的右视图 - 力扣(LeetCode)

思路:先递归右子树,再递归左子树,当某个深度首次到达时,对应的节点就在右视图中。

class Solution {
  public:
      vector<int> rightSideView(TreeNode* root) {
          vector<int> ans;
          auto dfs = [&](this auto&& dfs, TreeNode* node, int depth) -> void {
              if (!node)   return;
                       
              if (depth == ans.size()) { // 这个深度首次遇到
                  ans.push_back(node->val);
              }
              dfs(node->right, depth + 1); // 先递归右子树,保证首次遇到的一定是最右边的节点
              dfs(node->left, depth + 1);
          };
          dfs(root, 0);
          return ans;
      }
  };

235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)

利用二叉搜索树的性质决定往左还是往右,递归地查找。

如果p q分别在左右子树,则返回当前节点。


class Solution {
  public:
      TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
          int x = root->val;
          if(p->val < x && q->val < x)  return lowestCommonAncestor(root->left , p , q);
          else if(p->val > x && q->val > x)  return lowestCommonAncestor(root->right , p , q);
          else return root;
      }
  };

695. 岛屿的最大面积 - 力扣(LeetCode)

可以不用visit数组,把访问过的grid[x][y]全部置0

class Solution {
  public:
      int maxAreaOfIsland(vector<vector<int>>& grid) {
          int res = 0;
          int dirs[4][2] = {{-1 , 0} , {0 , 1} , {1 , 0} , {0 , -1}};
          int m = grid.size() , n = grid[0].size();
          int cnt = 0;
          auto dfs = [&](this auto&& dfs , int x , int y)->void{
              grid[x][y] = 0; //注意先把当前(x,y)置0
            for (int i = 0; i < 4; i++) {
              int nextx =  x + dirs[i][0];
              int nexty =  y + dirs[i][1]; 
              if(nextx < 0 || nextx >= m || nexty < 0 || nexty >= n)  continue;
              if(grid[nextx][nexty] == 1){
                cnt ++;
                grid[nextx][nexty] = 0;
                dfs(nextx , nexty);
              }
            }             
          };

          for (int i = 0; i < m; i++) {
             for (int j = 0; j < n; j++) {
                if(grid[i][j] == 1){
                  cnt = 1;
                  dfs(i , j);
                  res = max(res , cnt);
                }
             }
          }
          return res;
      }
  };

posted @ 2025-04-15 22:51  七龙猪  阅读(1)  评论(0)    收藏  举报
-->