返回

从LeetCode到动画:用代码重现螺旋矩阵之美

前端

螺旋矩阵是一种将数字按顺时针螺旋形排列的矩阵。LeetCode上的“螺旋矩阵II”问题要求我们创建一个螺旋矩阵,其中每个单元格的值等于它到最近边缘的曼哈顿距离。这个曼哈顿距离很容易理解:对于单元格(x, y),其曼哈顿距离定义为|x| + |y|。

为了创建动画,我首先构建了一个基本的HTML结构,其中包含一个用于渲染动画的画布元素。然后,我使用JavaScript来实现算法并将其与画布元素连接起来。当算法运行时,它将数字写入画布,同时更新动画以显示数字的排列方式。

整个过程对我来说是一个非常有趣的学习经历。不仅让我更深入地理解了螺旋矩阵算法,还让我对动画在算法可视化中的应用有了新的认识。如果您想了解更多关于这个项目的信息,或者想查看代码,欢迎访问我的GitHub页面。

以下是动画构建的代码示例:

<!DOCTYPE html>
<html>
<head>
  
</head>
<body>
  <canvas id="canvas" width="500" height="500"></canvas>

  <script>
    // 获取画布元素
    const canvas = document.getElementById('canvas');

    // 获取画布上下文
    const ctx = canvas.getContext('2d');

    // 创建螺旋矩阵
    const matrix = createSpiralMatrix(10);

    // 将矩阵渲染到画布上
    renderMatrix(ctx, matrix);

    // 动画函数
    function animate() {
      // 清除画布
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // 将矩阵渲染到画布上
      renderMatrix(ctx, matrix);

      // 更新矩阵
      updateMatrix(matrix);

      // 请求下一次动画帧
      requestAnimationFrame(animate);
    }

    // 启动动画
    animate();

    // 创建螺旋矩阵
    function createSpiralMatrix(n) {
      const matrix = [];

      for (let i = 0; i < n; i++) {
        matrix[i] = [];
        for (let j = 0; j < n; j++) {
          matrix[i][j] = 0;
        }
      }

      let x = 0;
      let y = 0;
      let direction = 'right';
      let count = 1;

      while (count <= n * n) {
        matrix[x][y] = count++;

        switch (direction) {
          case 'right':
            if (y + 1 < n && matrix[x][y + 1] === 0) {
              y++;
            } else {
              direction = 'down';
            }
            break;
          case 'down':
            if (x + 1 < n && matrix[x + 1][y] === 0) {
              x++;
            } else {
              direction = 'left';
            }
            break;
          case 'left':
            if (y - 1 >= 0 && matrix[x][y - 1] === 0) {
              y--;
            } else {
              direction = 'up';
            }
            break;
          case 'up':
            if (x - 1 >= 0 && matrix[x - 1][y] === 0) {
              x--;
            } else {
              direction = 'right';
            }
            break;
        }
      }

      return matrix;
    }

    // 将矩阵渲染到画布上
    function renderMatrix(ctx, matrix) {
      for (let i = 0; i < matrix.length; i++) {
        for (let j = 0; j < matrix[i].length; j++) {
          ctx.fillStyle = 'black';
          ctx.fillRect(i * 50, j * 50, 50, 50);

          ctx.fillStyle = 'white';
          ctx.font = 'bold 20px Arial';
          ctx.textAlign = 'center';
          ctx.textBaseline = 'middle';
          ctx.fillText(matrix[i][j], i * 50 + 25, j * 50 + 25);
        }
      }
    }

    // 更新矩阵
    function updateMatrix(matrix) {
      for (let i = 0; i < matrix.length; i++) {
        for (let j = 0; j < matrix[i].length; j++) {
          matrix[i][j]++;
        }
      }
    }
  </script>
</body>
</html>

我希望这篇文章对您有所帮助!如果您有任何问题或建议,请随时发表评论。