从Offer敲门到掘金打卡:挑战2104. 子数组范围和题海漫漫,勇者无畏
2023-09-27 00:36:40
【刷题日记】2104. 子数组范围和
踏上春招的征途,我决定拾起许久没有进行的刷题习惯,而2104. 子数组范围和则是我的第一站。
题目
给你一个整数数组nums,和一个查询数组queries,其中queries[i]是[start_i, end_i]。
对于每个查询,返回数组nums中在范围[start_i, end_i]中的元素的总和。
示例 1:
输入:nums = [1,2,3,4,5], queries = [[1,3],[0,1],[2,4],[2,4],[3,4]]
输出:[9,3,15,15,11]
解释:
nums[1] + nums[2] + nums[3] = 9
nums[0] + nums[1] = 3
nums[2] + nums[3] + nums[4] = 15
nums[2] + nums[3] + nums[4] = 15
nums[3] + nums[4] = 11
示例 2:
输入:nums = [10,5,-2,-3,7,5,5,2,1], queries = [[0,4],[1,2],[0,7],[3,7],[3,7],[2,6]]
输出:[23,-3,18,18,18,17]
解释:
nums[0] + nums[1] + nums[2] + nums[3] + nums[4] = 23
nums[1] + nums[2] = -3
nums[0] + nums[1] + nums[2] + nums[3] + nums[4] + nums[5] + nums[6] + nums[7] + nums[8] = 18
nums[3] + nums[4] + nums[5] + nums[6] + nums[7] = 18
nums[3] + nums[4] + nums[5] + nums[6] + nums[7] = 18
nums[2] + nums[3] + nums[4] + nums[5] + nums[6] = 17
解题思路
对于给定的查询数组,我们可以计算每个查询的范围和,然后将结果存储在数组中。在计算范围和时,我们可以使用动态规划来优化性能。
动态规划算法
我们首先定义一个状态数组dp,其中dp[i]表示nums数组中以索引i结尾的子数组的和。然后,我们使用以下递推公式来计算dp数组:
dp[i] = dp[i-1] + nums[i]
一旦我们计算了dp数组,我们就可以通过以下方式计算每个查询的范围和:
query_sum = dp[end_i] - dp[start_i-1]
Java代码
class Solution {
public int[] subarraySumQueries(int[] nums, int[][] queries) {
int[] dp = new int[nums.length+1];
for (int i = 1; i < dp.length; i++) {
dp[i] = dp[i-1] + nums[i-1];
}
int[] result = new int[queries.length];
for (int i = 0; i < queries.length; i++) {
int start = queries[i][0];
int end = queries[i][1];
result[i] = dp[end+1] - dp[start];
}
return result;
}
}
Python代码
def subarraySumQueries(nums, queries):
dp = [0] * (len(nums)+1)
for i in range(1, len(dp)):
dp[i] = dp[i-1] + nums[i-1]
result = []
for query in queries:
start = query[0]
end = query[1]
result.append(dp[end+1] - dp[start])
return result
C++代码
class Solution {
public:
vector<int> subarraySumQueries(vector<int>& nums, vector<vector<int>>& queries) {
vector<int> dp(nums.size()+1, 0);
for (int i = 1; i < dp.size(); i++) {
dp[i] = dp[i-1] + nums[i-1];
}
vector<int> result;
for (auto& query : queries) {
int start = query[0];
int end = query[1];
result.push_back(dp[end+1] - dp[start]);
}
return result;
}
};
总结
通过这道题,我复习了动态规划的思想和算法,并将其应用到了实际的问题中。在解决问题的过程中,我遇到了几个难点:
- 如何定义状态数组dp。
- 如何使用递推公式来计算dp数组。
- 如何使用dp数组来计算每个查询的范围和。
通过反复思考和查阅资料,我最终解决了这些问题,并得到了正确的答案。这让我对动态规划有了更深入的理解,也对自己的编程能力有了更多的信心。
在未来的刷题过程中,我会继续努力,争取取得更好的成绩。我相信,只要坚持不懈,终能有所收获。