递归与金字塔结构:递归实现重量计算问题咨询
递归计算对象承重的解决方案
我明白递归一开始确实容易绕晕,尤其是涉及到二维数组(多列/多行)的结构时,咱们一步步拆解问题,先搞清楚核心逻辑,再落地到代码上。
先把承重规则理清楚
你提到的规则我再明确下:
每个对象的承重 = 自身重量 + 上方所有对象承重的一半之和;最顶部的对象没有上方对象,所以它的承重就是自身重量。
举个一维堆叠的例子你就懂了:
比如从上到下有3个对象:A(重量10)、B(重量20)、C(重量30)
- A的承重:10(没上方对象,直接用自身重量)
- B的承重:20 + 10/2 = 25
- C的承重:30 + 25/2 = 42.5
如果是二维结构(比如网格),假设一个对象上方有两个对象,那就是自身重量加上这两个对象承重各取一半的总和。
如何检测数组是多列/多行(二维)
首先得判断输入的数组是一维还是二维,这里给你个简单的检测逻辑(以JavaScript为例):
function is2DArray(arr) { // 检查数组的第一个元素是不是数组,且数组不为空 return Array.isArray(arr) && arr.length > 0 && Array.isArray(arr[0]); }
比如[{weight:10}, {weight:20}]是一维数组(单列),[[objA, objB], [objC, objD]]就是二维数组(两行两列)。
实现递归计算承重
递归的关键是找终止条件和递归公式,咱们分一维和二维两种情况来写:
一维数组的递归实现
针对垂直堆叠的单列对象,递归函数如下:
function calculateWeight1D(arr, index = arr.length - 1) { // 终止条件:最顶部的对象(索引0),直接返回自身重量 if (index === 0) { return arr[index].weight; } // 递归计算上方一个对象的承重,再套公式 const upperWeight = calculateWeight1D(arr, index - 1); return arr[index].weight + upperWeight / 2; } // 示例使用 const stack1D = [{weight:10}, {weight:20}, {weight:30}]; console.log(calculateWeight1D(stack1D)); // 输出42.5,对应最下方的C的承重
二维数组的递归实现
假设二维数组的行是从上到下排列的(row=0是最顶部一行),每个对象的正上方是上一行同列的对象:
function calculateWeight2D(arr, row, col) { // 终止条件:最顶部一行的对象,没有上方对象 if (row === 0) { return arr[row][col].weight; } // 递归计算正上方对象的承重 const upperWeight = calculateWeight2D(arr, row - 1, col); return arr[row][col].weight + upperWeight / 2; } // 示例使用 const stack2D = [ [{weight:10}, {weight:15}], // 第一行(最顶部) [{weight:20}, {weight:25}], // 第二行 [{weight:30}, {weight:35}] // 第三行 ]; // 计算第三行第一列的对象承重 console.log(calculateWeight2D(stack2D, 2, 0)); // 输出42.5
如果你的作业里,二维数组中一个对象上方有多个对象(比如下方对象的左上方和右上方都有对象),只需要修改递归部分,把所有上方对象的承重都取一半加起来:
// 假设对象arr[row][col]的上方是arr[row-1][col-1](左上方)和arr[row-1][col+1](右上方) function calculateWeight2DMultiUpper(arr, row, col) { if (row === 0) { return arr[row][col].weight; } let totalUpperHalf = 0; // 检查左上方是否存在(防止越界) if (col - 1 >= 0) { totalUpperHalf += calculateWeight2DMultiUpper(arr, row - 1, col - 1) / 2; } // 检查右上方是否存在(防止越界) if (col + 1 < arr[row-1].length) { totalUpperHalf += calculateWeight2DMultiUpper(arr, row - 1, col + 1) / 2; } return arr[row][col].weight + totalUpperHalf; }
整合检测与计算
最后写个主函数,自动识别数组类型,调用对应的递归方法:
function calculateObjectWeight(arr, position = {}) { if (is2DArray(arr)) { const { row, col } = position; if (typeof row !== 'number' || typeof col !== 'number') { throw new Error("二维数组需要传入row和col参数,指定要计算的对象位置"); } return calculateWeight2D(arr, row, col); } else { // 一维数组默认计算最下方的对象,也可以指定index const index = position.index !== undefined ? position.index : arr.length - 1; return calculateWeight1D(arr, index); } } // 测试一维数组 console.log(calculateObjectWeight(stack1D)); // 42.5 // 测试二维数组第三行第二列的对象 console.log(calculateObjectWeight(stack2D, {row:2, col:1})); // 51.25
递归核心思路再强调下
- 终止条件必须明确:没有上方对象时,承重就是自身重量,这是递归的“出口”,不然会无限循环。
- 拆解问题:计算当前对象的承重,只需要搞定上方对象的承重,而上方对象的承重又能用同一个函数计算,这就是递归的本质。
- 二维结构要明确“上方对象”的定义:是正上方,还是多个方向的上方,根据你的作业需求调整就行。
如果还有具体的细节(比如用的是Python/Java,或者数组结构有特殊要求),可以再补充,咱们再细化调整。
内容的提问来源于stack exchange,提问作者user9501082
相关产品推荐
相关产品推荐

