如何使用reduce方法无循环生成帕斯卡三角的下一行?
如何用reduce方法将帕斯卡三角的一行转换为下一行
嘿,我来帮你搞定这个问题!帕斯卡三角的下一行遵循一个简单规则:除了首尾的1,每个元素都是上一行中相邻两个元素的和。要只用reduce(或类似的折叠操作,部分语言中fold与reduce功能相近,符合题目要求)实现这个转换,我们可以利用累加器构建中间的相邻和数组,再补充首尾的1即可。
JavaScript 实现
在JavaScript中,Array.reduce()支持自定义初始值,我们可以用它生成相邻元素的和数组,再拼接首尾的1:
function getNextPascalRow(currentRow) { // 用reduce生成相邻元素的和组成的中间数组 const middle = currentRow.reduce((acc, val, idx) => { // 跳过最后一个元素,因为没有下一个元素可以相加 if (idx < currentRow.length - 1) { acc.push(val + currentRow[idx + 1]); } return acc; }, []); // 首尾添加1,得到下一行 return [1, ...middle, 1]; } // 测试示例 console.log(getNextPascalRow([1])); // [1, 1] console.log(getNextPascalRow([1, 1])); // [1, 2, 1] console.log(getNextPascalRow([1, 2, 1])); // [1, 3, 3, 1]
关键点解释:
- 初始累加器
acc是一个空数组,遍历当前行时,只要不是最后一个元素,就将它与下一个元素相加,结果推入累加器。 - 最后用展开运算符把
1、中间数组、1拼接起来,就是帕斯卡三角的下一行。
Kotlin 实现
Kotlin中reduce默认的累加器类型与元素类型一致,所以我们可以用foldIndexed(带初始值和索引的折叠操作,符合题目对reduce方法的广义要求)来实现:
fun getNextPascalRow(currentRow: List<Int>): List<Int> { val middle = currentRow.foldIndexed(mutableListOf<Int>()) { index, acc, num -> if (index > 0) { // 将当前元素与前一个元素相加,添加到累加器 acc.add(currentRow[index - 1] + num) } acc } return listOf(1) + middle + listOf(1) } // 测试 fun main() { println(getNextPascalRow(listOf(1))) // [1, 1] println(getNextPascalRow(listOf(1, 1))) // [1, 2, 1] println(getNextPascalRow(listOf(1, 2, 1))) // [1, 3, 3, 1] }
关键点解释:
foldIndexed提供了索引参数,我们从第二个元素(index > 0)开始,将当前元素与前一个元素相加,结果存入累加器列表。- 最后拼接首尾的
1得到下一行。
Java 8+ Streams 实现
Java的Stream.reduce()可以结合ArrayList作为累加器,实现类似的逻辑:
import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; public class PascalTriangle { public static List<Integer> getNextPascalRow(List<Integer> currentRow) { if (currentRow.isEmpty()) { return List.of(1); } // 用reduce生成中间的相邻和数组 List<Integer> middle = IntStream.range(0, currentRow.size() - 1) .mapToObj(i -> currentRow.get(i) + currentRow.get(i + 1)) .reduce(new ArrayList<>(), (acc, val) -> { acc.add(val); return acc; }, (acc1, acc2) -> { acc1.addAll(acc2); return acc1; }); // 拼接首尾的1 List<Integer> nextRow = new ArrayList<>(); nextRow.add(1); nextRow.addAll(middle); nextRow.add(1); return nextRow; } public static void main(String[] args) { System.out.println(getNextPascalRow(List.of(1))); // [1, 1] System.out.println(getNextPascalRow(List.of(1, 1))); // [1, 2, 1] System.out.println(getNextPascalRow(List.of(1, 2, 1))); // [1, 3, 3, 1] } }
关键点解释:
- 先用
IntStream.range生成索引范围,计算相邻元素的和,再用reduce将这些和收集到ArrayList中(第三个参数是并行流时的合并逻辑,这里串行流也可以保留)。 - 最后手动添加首尾的
1,得到下一行。
内容的提问来源于stack exchange,提问作者prompteus
相关产品推荐
相关产品推荐

