1.2算法及其描述

1.2.1什么是算法

算法是对特定问题求解步骤的一种描述,它是指令的有限序列,其中每条指令表示计算机一个或的哥操作。

算法的5个特性:有穷性,可行性,确定性,输入性,输出性。

1.2.2算法描述

算法描述是指对设计出的算法用一种方式进行详细的描述以便于人交流。算法描述可以使用程序流程图,自然语言或者伪代码。

1.2.3C++语言描述算法的特点

前面有些基础知识就略过,主要讲讲函数模板和类模板。

函数模板:

函数模板是对一组函数的描述,它不是一个真实的函数,编译系统不产生任何执行代码。当编译系统在程序中发现有与函数模板中相匹配的函数调用时便生成一个重载函数,该重载函数的函数体与函数模板中的函数体相同,该重载函数就是模板函数。声明函数模板的一般格式如下:

template <类型形参表>

返回类型 函数名(形参表)

{

        函数体;

}

类模板:

类模板和函数模板相似。用于实现类所需的数据类型参数化。定义类模板的一般格式如下:

template <类型形参表>

class 类模板名

{

        类模板实现语句;

}

类模板不能直接使用,必须先实例化为相应的模板类,再定义该类模板的对象,之后才能使用。创建模板类的一般格式如下:

类模板名<类型实参表> 对象表;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
问题A:给定N个石头的重量,找到一对重量差为D的石头。 函数F的输入为一个长度为N的数组weights和一个实数D,表示每个石头的重量和目标重量差。函数的输出是一个长度为2的数组,表示找到的一对石头的下标,如果不存在这样的石头对,则返回空数组。 问题B:首先,我们可以使用一个哈希表来存储每个石头的重量及其对应的下标,然后遍历每个石头,查找是否存在另一个石头的重量为当前石头的重量加上D或减去D。如果存在,则返回这两个石头的下标。 时间复杂度为O(N),空间复杂度为O(N),因为需要使用哈希表来存储石头的重量及其对应的下标。 同时,我们也可以实现O(N)的时间复杂度和O(1)的空间复杂度。我们可以先将石头按照重量从小到大排序,然后使用双指针法来查找一对石头的重量差为D。具体来说,我们可以使用两个指针i和j,分别指向已排序数组的开头和结尾。如果weights[j]-weights[i]>D,则向左移动指针i;如果weights[j]-weights[i]<D,则向右移动指针j;如果weights[j]-weights[i]=D,则返回这两个石头的下标。 时间复杂度为O(NlogN),因为需要排序;空间复杂度为O(1),因为只使用了常数个变量。 以下是C++代码实现: ```c++ #include <iostream> #include <vector> #include <unordered_map> #include <algorithm> using namespace std; vector<int> findStonePair(vector<double>& weights, double D) { unordered_map<double, int> m; for (int i = 0; i < weights.size(); i++) { m[weights[i]] = i; } for (int i = 0; i < weights.size(); i++) { double target1 = weights[i] + D; double target2 = weights[i] - D; if (m.count(target1) && m[target1] != i) { return vector<int>{i, m[target1]}; } if (m.count(target2) && m[target2] != i) { return vector<int>{i, m[target2]}; } } return vector<int>{}; } vector<int> findStonePair2(vector<double>& weights, double D) { sort(weights.begin(), weights.end()); int i = 0, j = 1; while (j < weights.size()) { double diff = weights[j] - weights[i]; if (diff == D) { return vector<int>{i, j}; } else if (diff < D) { j++; } else { i++; } } return vector<int>{}; } int main() { // Test case 1: normal case vector<double> weights1{1.2, 2.4, 3.6, 4.8, 6.0}; double D1 = 2.4; vector<int> res1 = findStonePair(weights1, D1); vector<int> ans1{0, 1}; sort(res1.begin(), res1.end()); sort(ans1.begin(), ans1.end()); assert(res1 == ans1); vector<int> res2 = findStonePair2(weights1, D1); sort(res2.begin(), res2.end()); assert(res2 == ans1); // Test case 2: no pair exists vector<double> weights2{1.2, 2.4, 3.6, 4.8, 6.0}; double D2 = 2.5; vector<int> res3 = findStonePair(weights2, D2); vector<int> ans2{}; assert(res3 == ans2); vector<int> res4 = findStonePair2(weights2, D2); assert(res4 == ans2); // Test case 3: all weights are the same vector<double> weights3{1.0, 1.0, 1.0, 1.0}; double D3 = 0.0; vector<int> res5 = findStonePair(weights3, D3); vector<int> ans3{0, 1}; sort(res5.begin(), res5.end()); sort(ans3.begin(), ans3.end()); assert(res5 == ans3); vector<int> res6 = findStonePair2(weights3, D3); sort(res6.begin(), res6.end()); assert(res6 == ans3); // Test case 4: only one stone vector<double> weights4{1.0}; double D4 = 0.0; vector<int> res7 = findStonePair(weights4, D4); vector<int> ans4{}; assert(res7 == ans4); vector<int> res8 = findStonePair2(weights4, D4); assert(res8 == ans4); cout << "All test cases passed."; return 0; } ``` 问题C:给定N个石头的重量,找到所有重量差为D的石头对,其中对(1,4)和对(4,1)被认为是同一对。 我们可以先按照重量从小到大排序,然后使用双指针法来查找一对石头的重量差为D。具体来说,我们可以使用两个指针i和j,分别指向已排序数组的开头和结尾。如果weights[j]-weights[i]>D,则向左移动指针i;如果weights[j]-weights[i]<D,则向右移动指针j;如果weights[j]-weights[i]=D,则将这两个石头的下标加入结果集合中,然后向右移动指针i,直到weights[j]-weights[i]>D为止。 时间复杂度为O(max(R, N)),其中R是结果对数,空间复杂度为O(1)。 以下是C++代码实现: ```c++ #include <iostream> #include <vector> #include <algorithm> using namespace std; vector<vector<int>> findStonePairs(vector<double>& weights, double D) { sort(weights.begin(), weights.end()); vector<vector<int>> res; int i = 0, j = 1; while (j < weights.size()) { double diff = weights[j] - weights[i]; if (diff == D) { res.push_back(vector<int>{i, j}); i++; } else if (diff < D) { j++; } else { i++; } } return res; } int main() { // Test case 1: normal case vector<double> weights1{1.2, 2.4, 3.6, 4.8, 6.0}; double D1 = 2.4; vector<vector<int>> res1 = findStonePairs(weights1, D1); vector<vector<int>> ans1{{0, 1}, {1, 2}, {2, 3}, {3, 4}}; sort(res1.begin(), res1.end()); sort(ans1.begin(), ans1.end()); assert(res1 == ans1); // Test case 2: no pair exists vector<double> weights2{1.2, 2.4, 3.6, 4.8, 6.0}; double D2 = 2.5; vector<vector<int>> res2 = findStonePairs(weights2, D2); vector<vector<int>> ans2{}; assert(res2 == ans2); // Test case 3: all weights are the same vector<double> weights3{1.0, 1.0, 1.0, 1.0}; double D3 = 0.0; vector<vector<int>> res3 = findStonePairs(weights3, D3); vector<vector<int>> ans3{{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}}; sort(res3.begin(), res3.end()); sort(ans3.begin(), ans3.end()); assert(res3 == ans3); // Test case 4: only one stone vector<double> weights4{1.0}; double D4 = 0.0; vector<vector<int>> res4 = findStonePairs(weights4, D4); vector<vector<int>> ans4{}; assert(res4 == ans4); cout << "All test cases passed."; return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值