【问题标题】:C++ *Diagonal Difference* Problem, Where Am I Going Wrong?C++ *对角差*问题,我哪里错了?
【发布时间】:2020-01-02 02:28:43
【问题描述】:

我仍然是 C++ 的初学者,并试图解决“对角线差异”问题。

给定一个方阵,我应该计算其对角线之和之间的绝对差。

例如:

11 2 4
4 5 6
10 8 -12

主要对角线:

11
   5
     -12

次对角线:

     4
   5
10

解决方案是 15。(绝对值)

我的代码在某些测试用例中有效,但不是全部。我被困住了,想知道我哪里出错了。这是我目前所拥有的:

int diagonalDifference(vector<vector<int>> arr) 
{
    int firstTotal = 0;
    int secondTotal = 0;
    int absTotal = 0; 
    int firstMiddleNumbers = 0;
    int secondMiddleNumbers = 0;
    int lastY = arr.size()-1;
    int lastX = arr[0].size()-1;

    for(int i = 1; i < arr.size(); i++)
    {
        firstMiddleNumbers += arr[i][i];
    }

    firstTotal = arr[0][0] + firstMiddleNumbers + arr[lastX][lastY];

    for(int j = arr[0].size()-1; j > 0; j--)
    {
        secondMiddleNumbers += arr[j][j]; 
    }

    secondTotal = arr[lastX][0] + secondMiddleNumbers + arr[0][lastY];

    absTotal = abs(firstTotal-secondTotal);

    return absTotal;

}

编辑:

更新的解决方案,仍在努力将其放入一个 for 循环中。

int diagonalDifference(vector<vector<int>> arr) 
{
    int firstMiddleNumbers = 0;
    int secondMiddleNumbers = 0;
    int k = 0;

    for(int i = 0; i <= arr.size()-1; i++)
    {
        firstMiddleNumbers += arr[i][i];
    }
    for(int j = arr[0].size()-1; j >= 0; j--)
    {
        secondMiddleNumbers += arr[j][k]; 
        k++;
    }
    return abs(firstMiddleNumbers-secondMiddleNumbers);
}

【问题讨论】:

  • 这里没有递归,首先不清楚递归在这里有什么目的。忽略递归,正确的解决方案将只涉及一个for 循环,并且只有两个变量,而不是七个。两个和,初始化为 0,一个循环,将适当的值添加到两个和。最后,减去两个和并取绝对值——你不认为这真的比所有这些复杂性要简单得多吗?
  • 您的代码没有使用递归来解决问题。
  • @SamVarshavchik 其中一个测试用例涉及一个包含超过 500 个元素的 2D 向量,因此它需要是动态的,我误会了递归,我将删除它。
  • @boyanhristov96 是的,对不起。我不是故意输入的,我已经编辑了。
  • 好的,我在第一条评论中写的几乎所有内容都是正确的。

标签: c++


【解决方案1】:

您只需要一个正在运行的“差异总计”变量,并且只需要一个 for 循环。

提示:每列访问一次。您只需要一个 for 循环,因为它是一个方阵。朴素的双重嵌套 for 循环(索引 ij)方法可以隐式折叠成一个循环,其中 column = irowA = irowB= (n - 1) - i(从零开始)。这是因为整数加法是可交换的,因此您可以对表达式的加法和减法项重新排序。

简单来说,根据你的例子:

(11 + 5 - 12) - (10 + 5 + 4)(11 - 10) + (5 - 5) + (-12 - 4) 相同,您可以利用这一事实来简化您的代码以访问每一列一次,将差值累积在单个变量中,而不是尝试计算对角线并存储中间结果。

【讨论】:

  • 感谢您的建议!我使用两个 for 循环让它工作,并用我的解决方案编辑了上面的问题,现在尝试只使用一个 for 循环。
  • 太好了!您的解决方案似乎很好,只需一个循环即可获得奖励积分:D
  • 你可能需要处理一个极端情况,即当你得到一个无效的零大小矩阵(大小为0)时处理,这样你就没有无效的数组访问
【解决方案2】:

您无法将int iunsigned long arr.size() 进行比较。将arr.size() 存储在另一个int 变量中,例如int n = arr.size();,然后使用它。

【讨论】: