本文主要是介绍leetcode 3080,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
leetcode 3080
题目
例子
思路
创建数组,记录nums 的值 对应的id, 按照大小排序。
代码实现
class Solution {
public:vector<long long> unmarkedSumArray(vector<int>& nums, vector<vector<int>>& queries) {vector<long long> res;int n = nums.size();/*ids 数组是为了记录nums的val的index的序列。举个例子:nums = [1,2,2,1,2,3,1]ids[0] [1] [2] 对应的值是0, 3, 6因为nums[0], nums[3], nums[6] 的值都是1,是最小值;*/vector<int> ids(n);iota(ids.begin(), ids.end(), 0);ranges::stable_sort(ids, [&](int i, int j) { return nums[i] < nums[j]; });for(int i=0; i<queries.size(); i++){int q_id = queries[i][0];int q_num = queries[i][1];// 被标记的id 的nums的值,设置为0, 这样计算sum 的时候,直接默认标记了。// 已知nums 是正整数数组,正整数的范围是 >0 的。nums[q_id] = 0;int j =0;while(q_num > 0 && j<n){int num_id = ids[j];if(nums[num_id] == 0){j++;}else{nums[num_id] = 0;q_num--;j++;}}long long sum = std::accumulate(nums.begin(), nums.end(), 0);res.push_back(sum);}return res;}
};
long long sum = std::accumulate(nums.begin(), nums.end(), 0LL);
解决了runtime error , 还是有超时问题。
class Solution {
public:vector<long long> unmarkedSumArray(vector<int>& nums, vector<vector<int>>& queries) {vector<long long> res;int n = nums.size();long long sum = std::accumulate(nums.begin(), nums.end(), 0LL);/*ids 数组是为了记录nums的val的index的序列。举个例子:nums = [1,2,2,1,2,3,1]ids[0] [1] [2] 对应的值是0, 3, 6因为nums[0], nums[3], nums[6] 的值都是1,是最小值;*/vector<int> ids(n);iota(ids.begin(), ids.end(), 0);ranges::stable_sort(ids, [&](int i, int j) { return nums[i] < nums[j]; });int j =0;for(int i=0; i<queries.size(); i++){int q_id = queries[i][0];int q_num = queries[i][1];// 被标记的id 的nums的值,设置为0, 这样计算sum 的时候,直接默认标记了。// 已知nums 是正整数数组,正整数的范围是 >0 的。sum = sum - nums[q_id];nums[q_id] = 0;while(q_num > 0 && j<n){int num_id = ids[j];if(nums[num_id] > 0){sum = sum - nums[num_id];nums[num_id] = 0;q_num--;}j++;} res.push_back(sum);}return res;}
};
减少while or loop 里的计算or 判断,可以减少执行时间。
stable_sort 函数
对于 ranges::stable_sort(ids, [&](int i, int j) { return nums[i] < nums[j]; });
这样的调用方式,我们可以简单地了解其实现原理。由于 ranges::stable_sort
是 C++20 中引入的新函数,其具体实现可能会因标准库的不同而有所差异。以下是一个简单的伪代码示例,展示了 ranges::stable_sort
的可能实现:
template <class RandomAccessIterator, class Compare>
void ranges::stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {if (first == last) return;using value_type = typename std::iterator_traits<RandomAccessIterator>::value_type;std::vector<value_type> temp(first, last); // 将范围内的元素复制到临时数组中// 使用 lambda 表达式作为比较函数auto lambda_comp = [&](int i, int j) { return comp(temp[i], temp[j]); };std::stable_sort(temp.begin(), temp.end(), lambda_comp); // 使用 std::stable_sort 对临时数组进行排序std::copy(temp.begin(), temp.end(), first); // 将排序后的元素复制回原始范围
}
上述伪代码简单地描述了 ranges::stable_sort
的实现思路。首先,将范围内的元素复制到临时数组中,然后使用 lambda 表达式作为比较函数,对临时数组进行排序,最后将排序后的元素复制回原始范围。这种实现方式保证了稳定排序的特性。
需要注意的是,实际的 ranges::stable_sort
实现可能会更加复杂,因为它需要考虑范围操作、迭代器特性、元素类型等多个因素。
accumulate 函数
std::accumulate
是 C++ 标准库中的一个算法函数,用于对一个范围内的元素进行累积操作。它定义在 <numeric>
头文件中。
std::accumulate
函数的原型如下:
template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );
其中:
InputIt
是输入迭代器的类型,用于指定范围的开始和结束位置。T
是累积结果的类型,也是初始值的类型。first
和last
分别是指向范围的起始和结束位置的迭代器。init
是初始值,用于初始化累积结果。
std::accumulate
函数会从 first
到 last
遍历范围内的元素,对它们进行累积操作。具体而言,它将初始值 init
和范围内的每个元素进行二元操作(通常是加法),并将结果存储在累积结果中。最终返回累积结果。
以下是一个示例用法:
#include <iostream>
#include <vector>
#include <numeric>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};// 使用 std::accumulate 函数计算和int sum = std::accumulate(vec.begin(), vec.end(), 0);std::cout << "Sum of elements in the vector: " << sum << std::endl;return 0;
}
在这个示例中,我们使用 std::accumulate
函数计算了一个 std::vector
中所有元素的和,并将结果打印到控制台上。
std::accumulate
函数在处理累积操作时非常方便,可以用于对容器中的元素进行求和、求积、计算平均值等操作。希望这个介绍能够帮助您理解 std::accumulate
函数的用法。如果您有任何其他问题,请随时告诉我。
这篇关于leetcode 3080的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!