数组的三角和
问题描述
给定一个下标从 0 开始的整数数组 nums
,其中每个元素都是 0 到 9 之间的数字。数组的三角和是通过以下操作最后剩下的元素:
- 若数组长度为 1,终止操作,该元素即为三角和
- 否则,创建新数组
newNums
,长度为原数组长度减 1 - 对于每个
0 <= i < 原数组长度 - 1
,newNums[i] = (nums[i] + nums[i+1]) % 10
- 用
newNums
替换nums
,重复步骤 1
请返回数组的三角和。
示例:
- 输入:
[1,2,3,4,5]
,输出:8
- 输入:
[5]
,输出:5
约束条件:
1 <= nums.length <= 1000
0 <= nums[i] <= 9
解题思路
解法一:模拟法(暴力迭代)
最直观的思路是严格按照题目描述的操作流程进行模拟:
- 初始数组为
nums
- 当数组长度大于 1 时,不断生成新数组
- 新数组的每个元素是原数组相邻元素之和对 10 取余
- 替换原数组,重复操作直到数组长度为 1
- 返回最后剩下的元素
这种方法实现简单,直接反映了问题的操作过程,但需要不断创建新数组,空间复杂度较高。
解法二:动态规划(空间优化)
观察发现,每一步的计算只依赖于上一步的结果,因此可以使用空间优化:
- 不需要创建新数组,直接在原数组上进行修改
- 从数组头部开始,依次计算新值并覆盖原位置
- 每次迭代后,有效长度减 1
- 重复操作直到有效长度为 1
- 数组第一个元素即为结果
这种方法复用了原数组空间,降低了空间复杂度。
代码实现
C++ 实现
解法一:模拟法
#include <iostream>
#include <vector>
using namespace std;class Solution {
public:int triangularSum(vector<int>& nums) {while (nums.size() > 1) {vector<int> newNums;for (int i = 0; i < nums.size() - 1; ++i) {newNums.push_back((nums[i] + nums[i+1]) % 10);}nums = newNums;}return nums[0];}
};int main() {Solution solution;vector<int> nums1 = {1,2,3,4,5};cout << solution.triangularSum(nums1) << endl; // 输出: 8vector<int> nums2 = {5};cout << solution.triangularSum(nums2) << endl; // 输出: 5return 0;
}
解法二:空间优化法
#include <iostream>
#include <vector>
using namespace std;class Solution {
public:int triangularSum(vector<int>& nums) {int n = nums.size();// 每次迭代减少数组有效长度while (n > 1) {// 计算新值并覆盖原数组for (int i = 0; i < n - 1; ++i) {nums[i] = (nums[i] + nums[i+1]) % 10;}n--; // 有效长度减1}return nums[0];}
};int main() {Solution solution;vector<int> nums1 = {1,2,3,4,5};cout << solution.triangularSum(nums1) << endl; // 输出: 8vector<int> nums2 = {5};cout << solution.triangularSum(nums2) << endl; // 输出: 5return 0;
}
Python 实现
解法一:模拟法
def triangularSum(nums):while len(nums) > 1:# 生成新数组nums = [(nums[i] + nums[i+1]) % 10 for i in range(len(nums) - 1)]return nums[0]# 测试
print(triangularSum([1,2,3,4,5])) # 输出: 8
print(triangularSum([5])) # 输出: 5
解法二:空间优化法
def triangularSum(nums):n = len(nums)# 每次迭代减少有效长度while n > 1:# 在原数组上更新值for i in range(n - 1):nums[i] = (nums[i] + nums[i+1]) % 10n -= 1 # 有效长度减1return nums[0]# 测试
print(triangularSum([1,2,3,4,5])) # 输出: 8
print(triangularSum([5])) # 输出: 5
Java 实现
解法一:模拟法
import java.util.ArrayList;
import java.util.List;public class TriangularSum {public static int triangularSum(List<Integer> nums) {while (nums.size() > 1) {List<Integer> newNums = new ArrayList<>();for (int i = 0; i < nums.size() - 1; i++) {newNums.add((nums.get(i) + nums.get(i + 1)) % 10);}nums = newNums;}return nums.get(0);}public static void main(String[] args) {List<Integer> nums1 = new ArrayList<>();nums1.add(1);nums1.add(2);nums1.add(3);nums1.add(4);nums1.add(5);System.out.println(triangularSum(nums1)); // 输出: 8List<Integer> nums2 = new ArrayList<>();nums2.add(5);System.out.println(triangularSum(nums2)); // 输出: 5}
}
解法二:空间优化法
public class TriangularSum {public static int triangularSum(int[] nums) {int n = nums.length;// 每次迭代减少有效长度while (n > 1) {// 在原数组上更新值for (int i = 0; i < n - 1; i++) {nums[i] = (nums[i] + nums[i + 1]) % 10;}n--; // 有效长度减1}return nums[0];}public static void main(String[] args) {int[] nums1 = {1, 2, 3, 4, 5};System.out.println(triangularSum(nums1)); // 输出: 8int[] nums2 = {5};System.out.println(triangularSum(nums2)); // 输出: 5}
}
复杂度分析
解法 | 时间复杂度 | 空间复杂度 | 特点 |
---|---|---|---|
模拟法 | O(n²) | O(n²) | 实现简单,直观反映问题流程,空间消耗大 |
空间优化法 | O(n²) | O(1)(额外空间) | 复用原数组,空间效率高,实现稍复杂 |
- 时间复杂度:两种方法均为 O(n²),因为对于长度为 n 的数组,需要进行 n-1 次迭代,第 i 次迭代处理 n-i 个元素,总操作次数为 n+(n-1)+…+1 = n(n+1)/2 ≈ O(n²)
- 空间复杂度:模拟法需要不断创建新数组,总空间为 O(n²);优化法仅使用常数额外空间,空间复杂度为 O(1)(不计算输入数组本身)
总结
数组的三角和问题可以通过两种主要方法解决:
-
模拟法:严格按照题目描述的操作流程,不断生成新数组直到剩下一个元素。这种方法实现简单,易于理解,但空间复杂度较高。
-
空间优化法:通过在原数组上直接更新值,避免创建新数组,显著降低了空间复杂度。这种方法更适合处理较大规模的输入。
在实际应用中,推荐使用空间优化法,尤其是当数组长度较大时(接近 1000),可以节省大量内存空间。两种方法的时间复杂度相同,但空间优化法的空间效率优势明显。