JS奇数求和:从朴素循环到数学之美

奇数求和:从朴素循环到数学之美 ✨

计算从 1 开始的前 n 个奇数的和,这是一个常见的数学问题,也是编程练习中经常遇到的题目。解决这个问题的方法不止一种,从最直接的循环累加,到巧妙利用数学规律,不同的方法展现了不同的编程思维和效率。今天,我们就来探讨如何用两种方式来实现这个功能。

❓ 问题的提出:前 n 个奇数之和

我们需要编写一个函数,接收一个正整数 n 作为输入,并返回从 1 开始的前 n 个奇数的总和。

例如:

  • n 为 1 时,求 1 的和,结果是 1。
  • n 为 2 时,求 1, 3 的和,结果是 4。
  • n 为 3 时,求 1, 3, 5 的和,结果是 9。
  • n 为 4 时,求 1, 3, 5, 7 的和,结果是 16。

方法一:循环累加,朴素的实现

最直观的想法是,我们可以生成从 1 开始的前 n 个奇数,并将它们逐一相加。

/**
 * 求:从1开始的前n个奇数和
 *
 * 输入1,求1的和
 * 输入2,求1,3的和
 * 输入3,求1,3,5的和
 * 输入4,求1,3,5,7的和
 */

// 第一种方法:循环累加
function sum(n) {
  let result = 0; // 初始化总和为 0
  for (let i = 0; i < n; i++) {
    // 循环 n 次,生成前 n 个奇数
    // 第一个奇数 (i=0) 是 2*0+1 = 1
    // 第二个奇数 (i=1) 是 2*1+1 = 3
    // 第三个奇数 (i=2) 是 2*2+1 = 5
    // ...
    // 第 n 个奇数 (i=n-1) 是 2*(n-1)+1
    result += 2 * i + 1; // 将当前奇数加到总和中
  }
  return result; // 返回最终的总和
}

console.log(sum(1)); // 1
console.log(sum(2)); // 4
console.log(sum(3)); // 9
console.log(sum(4)); // 16
console.log(sum(5)); // 25

思路解析:

  1. 我们初始化一个变量 result 来存储总和,最初为 0。
  2. 使用一个 for 循环,循环 n 次。循环变量 i 从 0 开始递增到 n-1
  3. 在每次循环中,我们计算当前的奇数。观察奇数的规律:第一个奇数是 1 (当 i=0 时 2*0+1),第二个是 3 (当 i=1 时 2*1+1),第三个是 5 (当 i=2 时 2*2+1),以此类推。第 i+1 个奇数(也就是当循环变量为 i 时)可以表示为 2 * i + 1
  4. 将计算得到的当前奇数加到 result 中。
  5. 循环结束后,result 就存储了前 n 个奇数的总和,将其返回。

这种方法简单直观,易于理解,是解决这类问题的基本思路。它的时间复杂度是 O(n),因为需要循环 n 次。

方法二:发现规律,数学的魔法

仔细观察前面计算的结果:

  • n=1,和为 1
  • n=2,和为 4
  • n=3,和为 9
  • n=4,和为 16
  • n=5,和为 25

我们发现,前 n 个奇数的和似乎总是等于 n 的平方!即:

1 = 1 * 1
1 + 3 = 4 = 2 * 2
1 + 3 + 5 = 9 = 3 * 3
1 + 3 + 5 + 7 = 16 = 4 * 4
1 + 3 + 5 + 7 + 9 = 25 = 5 * 5

这个规律是真实存在的。从 1 开始的前 n 个奇数的和恰好等于 n 的平方。

有了这个发现,我们可以写出更简洁高效的代码:

// 第二种方法:利用数学规律
function sum(n) {
  return n * n; // 直接返回 n 的平方
}

console.log(sum(1)); // 1
console.log(sum(2)); // 4
console.log(sum(3)); // 9
console.log(sum(4)); // 16
console.log(sum(5)); // 25

思路解析:

这种方法直接利用了数学规律,函数只需要接收 n,然后计算 n * n 并返回即可。

这种方法的优势在于它的效率。它的时间复杂度是 O(1),因为无论 n 有多大,它都只需要一次乘法运算。这在处理非常大的 n 值时尤为重要。

证明这个数学规律(选读)

为什么前 n 个奇数的和等于 n 的平方呢?这里提供一个简单的几何解释:

考虑一个边长为 n 的正方形,它可以被分成 n * n 个小正方形。我们可以用“L形”来填充这个正方形:

  • 第一个“L形”是一个 1x1 的小正方形,包含 1 个格子(第一个奇数 1)。
  • 第二个“L形”包含 3 个格子(第二个奇数 3),围绕着第一个“L形”。
  • 第三个“L形”包含 5 个格子(第三个奇数 5),围绕着前两个“L形”。
  • n 个“L形”包含 2n - 1 个格子(第 n 个奇数)。

将这 n 个“L形”叠加起来,正好组成一个 n * n 的正方形。因此,前 n 个奇数的总和就等于 n * n

总结与选择

  • 方法一(循环累加):直观易懂,适合理解基本编程逻辑,时间复杂度 O(n)。
  • 方法二(数学规律):高效简洁,利用数学特性,时间复杂度 O(1),适用于需要高性能的场景。

在实际开发中,如果性能不是极致要求,方法一的可读性可能更高一些。但如果需要处理大量数据或者追求最高效率,方法二无疑是更好的选择。了解并掌握这两种不同的解决思路,可以帮助我们更好地选择合适的算法来解决问题。

你可能感兴趣的:(JS,javascript,开发语言,ecmascript)