You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中顺时针旋转矩阵外圈n步?

仅顺时针旋转矩阵外圈n步的解决方案

我来帮你搞定这个问题!你之前用的是整个矩阵旋转的逻辑(通常是转90度的经典写法),当然没法只转外圈,我们换个更精准的思路来实现你要的效果。

核心思路

要只转外圈,我们可以把外圈的元素单独提取出来形成一个环形数组,旋转这个数组后再放回原矩阵,这样就不会影响内圈的元素了。具体分四步走:

  1. 定位外圈边界
    对于m行k列的矩阵,外圈由四个部分组成:

    • 顶部行:第0行,从左到右所有列
    • 右侧列:最后一列,从第二行到最后一行(跳过顶部行已经取过的元素)
    • 底部行:最后一行,从倒数第二列到第一列(反向,跳过右侧列取过的元素)
    • 左侧列:第一列,从倒数第二行到第二行(反向,跳过底部和顶部行取过的元素)
  2. 提取外圈元素
    按照上面的顺序,把外圈所有元素收集到一个一维列表里,形成一个环形的序列。

  3. 处理旋转步数
    外圈元素的总数是 2*(m + k - 2),为了避免重复旋转(比如转15步和转1步在14个元素的外圈效果一样),我们把n取模这个总数,得到有效步数 n = n % total。

  4. 旋转并放回元素
    顺时针旋转n步,等价于把环形数组的最后n个元素移到最前面(比如数组[a,b,c,d]顺时针转1步就变成[d,a,b,c])。之后再把旋转后的元素按原来的顺序填回矩阵的外圈位置即可。

代码实现(以Java为例,其他语言思路一致)

public static void rotateOuterCircle(int[][] matrix, int n) {
    int rows = matrix.length;
    if (rows == 0) return;
    int cols = matrix[0].length;
    // 如果只有一行/一列,没有外圈可转,直接返回
    if (cols == 0 || rows == 1 || cols == 1) return;
    
    // 第一步:提取外圈元素到列表
    List<Integer> outerElements = new ArrayList<>();
    // 顶部行:左到右
    for (int j = 0; j < cols; j++) {
        outerElements.add(matrix[0][j]);
    }
    // 右侧列:上到下(跳过顶部行最后一个元素)
    for (int i = 1; i < rows; i++) {
        outerElements.add(matrix[i][cols - 1]);
    }
    // 底部行:右到左(跳过右侧列最后一个元素)
    for (int j = cols - 2; j >= 0; j--) {
        outerElements.add(matrix[rows - 1][j]);
    }
    // 左侧列:下到上(跳过底部行第一个和顶部行第一个元素)
    for (int i = rows - 2; i >= 1; i--) {
        outerElements.add(matrix[i][0]);
    }
    
    int totalElements = outerElements.size();
    n = n % totalElements;
    if (n == 0) return; // 步数为0,无需旋转
    
    // 第二步:旋转列表(顺时针n步 = 把最后n个元素移到前面)
    List<Integer> rotatedElements = new ArrayList<>();
    rotatedElements.addAll(outerElements.subList(totalElements - n, totalElements));
    rotatedElements.addAll(outerElements.subList(0, totalElements - n));
    
    // 第三步:把旋转后的元素放回矩阵
    int index = 0;
    // 填充顶部行
    for (int j = 0; j < cols; j++) {
        matrix[0][j] = rotatedElements.get(index++);
    }
    // 填充右侧列
    for (int i = 1; i < rows; i++) {
        matrix[i][cols - 1] = rotatedElements.get(index++);
    }
    // 填充底部行
    for (int j = cols - 2; j >= 0; j--) {
        matrix[rows - 1][j] = rotatedElements.get(index++);
    }
    // 填充左侧列
    for (int i = rows - 2; i >= 1; i--) {
        matrix[i][0] = rotatedElements.get(index++);
    }
}

测试你的示例

原4×5矩阵:

1 2 3 4 5
6 7 8 9 0
5 4 2 5 7
8 2 7 9 3

调用rotateOuterCircle(matrix, 1)后,输出完全符合你的预期:

6 1 2 3 4
5 7 8 9 5
8 4 2 5 0
2 7 9 3 7

为什么你之前的逻辑不适用?

你之前写的代码是整个矩阵旋转90度的经典写法,它会递归处理矩阵的每一层(包括内圈),而且是固定旋转90度,不是按指定步数旋转,所以完全不符合"仅转外圈n步"的需求。我们上面的方法只针对最外层元素操作,精准实现了你要的效果。

内容的提问来源于stack exchange,提问作者Vivank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:20:52