算法训练.15
目录
66.牛客网数字统计
66.1 题目解析:
66.2 算法思路:
66.3 代码演示:
67 牛客网:两个数组的交集
67.1 题目解析
67.2 算法思路:
67.3 代码演示:
哈希数组的布尔值含义:
hash1[kk] = true 的意思:
hash1[kk] = false 的意思:
具体执行流程示例:
第一步:标记 nums1 中的数字
第二步:检查 nums2 并收集交集
67.4 总结反思:
68 牛客网:点击消除
68.1 题目解析:
68.2 算法思路:
68.3 代码演示;
68.4 总结反思:
69 牛客网:牛牛的快递
69.1 题目解析:
69.2 算法思路:
69.3 代码演示:
哈喽大家好久不见,这个专题已经有将近2个月没有更新了,那么接下来我将(有空)就更新
不过更新频率不会很低。
66.牛客网数字统计
66.1 题目解析:
这个题目可是非常的简单,上面可都写着入门级别呢。
题目的意思也是很好理解,就是统计数字2出现的次数
66.2 算法思路:
关于这道题目呢,我有两种解法:
第一种就是采用取模,取到最后一位的数字,判断是不是2。之后再去掉最后一个位置即可。
第二种就是采用将这个数转化成字符串,然后遍历字符串,看看有几个字符2即可。
66.3 代码演示:
//第一种方法
int main()
{int L, R;cin >> L >> R;int count = 0;for (; L <= R; L++){int nums = L;if (nums % 10 == 2){count++;//最后一个数字等于2}nums / 10;//再去掉最后一个数字}cout << count << endl;return 0;
}
//第二中方法,将它转化为字符串处理
int main()
{int L, R;cin >> L >> R;int count = 0;for (; L <= R; L++){string nums = to_string(L);for (auto& kk : nums){if (kk == '2'){count++;}}}cout << count << endl;return 0;
}
67 牛客网:两个数组的交集
67.1 题目解析
本道题目,作者一开始做的时候,想的是可以优化暴力解法,但是发现行不通。(可能是我的代码能力不行吧)
67.2 算法思路:
其实这道题目,咱们把nums1放到哈希表中,然后在nums2中,快速的寻找手否有nums1中的这个元素。那么这个时候,快速查找,咱们说就需要哈希表。
所以就用到了哈希表,不过还是建议使用哈希数组。
注意这个地方有个比较棘手的问题,就是去重的问题,那么这个时候就需要用到哈希布尔了。
67.3 代码演示:
采用哈希数组的布尔值
bool hash1[1010] = { 0 };
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {vector<int> result;for (auto& kk : nums1){hash1[kk] = true;}for (auto& kk : nums2){if (hash1[kk]){result.push_back(kk);hash1[kk] = false;}}return result;
}
int main()
{vector<int> nums1 = {1,2,3,8};vector<int> nums2 = {8,2,2,3,8};vector<int> result = intersection(nums1,nums2);for (int k = 0; k < result.size(); k++){cout << result[k];if (k != result.size() - 1){cout << ",";}}cout << endl;return 0;
}
这个时候还是介绍一下哈希布尔吧:
哈希数组的布尔值含义:
hash1[kk] = true
的意思:
hash1[kk] = true; // 表示数字 kk 存在于第一个数组 nums1 中
相当于:标记数字 kk
已经出现过,做一个"存在"的记号。
hash1[kk] = false
的意思:
hash1[kk] = false; // 表示数字 kk 已经被处理过,避免重复添加
相当于:取消标记,防止同一个数字被多次添加到结果中。
具体执行流程示例:
假设:
nums1 = [1, 2, 2, 3] nums2 = [2, 2, 4]
第一步:标记 nums1 中的数字
for(auto& kk : nums1) {hash1[kk] = true; // 标记存在 }
执行后哈希数组状态:
-
hash1[1] = true
(数字1存在) -
hash1[2] = true
(数字2存在) -
hash1[3] = true
(数字3存在) -
其他都是
false
第二步:检查 nums2 并收集交集
for(auto& kk : nums2) {if(hash1[kk]) { // 如果数字存在于nums1中result.push_back(kk); // 添加到结果hash1[kk] = false; // 取消标记,避免重复} }
逐步执行:
-
kk = 2
:hash1[2] = true
→ 添加2到结果,设置hash1[2] = false
-
kk = 2
:hash1[2] = false
→ 不添加(避免重复) -
kk = 4
:hash1[4] = false
→ 不添加(不存在于nums1)
最终结果:[2]
可视化理解:
text
初始: hash1[所有数字] = false处理nums1后: hash1[1] = true ✓ 存在 hash1[2] = true ✓ 存在 hash1[3] = true ✓ 存在 其他都是 false ✗ 不存在处理nums2时: 遇到2: true → 添加到结果,然后设为false 再次遇到2: false → 跳过(避免重复添加)
总结:true
= "这个数字在第一个数组中出现过",false
= "这个数字要么没出现过,要么已经处理过了"。
67.4 总结反思:
本题需要用到哈希布尔。
68 牛客网:点击消除
68.1 题目解析:
这个题目就是消消乐的意思,很简单的一道题目。
68.2 算法思路:
这个题目也是有两种解法:
第一种就是两个两个字符的进行比较,类似于暴力解法。但是还是挺好用的。
第二种解法就是:采用栈,咱们知道,之前有一道题目是括号匹配的题目,那道题目用到的是栈的思想。这道题目与那道题目是一样的,也是用到了栈的思想。
68.3 代码演示;
int main() {string str;cin >> str;cin.ignore();int i = 0;while (i < str.size() - 1){if (str[i] == str[i + 1]){str.erase(i, 2);i = max(0, i - 1); // 回退一步,检查新的相邻字符}else{i++;}if (str.size() == 0){break;}}if (str.size() == 0){cout << 0 << endl;}else{cout << str << endl;}return 0;
}
方法二,采用栈
int main() {string str1;string str2;cin >> str2;cin.ignore();for (char ch : str2){if (str1.size() && str1.back() == ch) str1.pop_back();else str1 += ch;//栈为空或者是栈顶元素不等于当前元素}if (str1.size() == 0){cout << 0 << endl;}else{cout << str1 << endl;}return 0;
}
这个栈不一定非得使用栈,而是一般咱们都是使用字符串代替栈的。
68.4 总结反思:
对于这道题目,咱们要想到栈的用法才比较好做。
69 牛客网:牛牛的快递
69.1 题目解析:
这道题目就是考你的简单的逻辑能力。
69.2 算法思路:
那么对于这道题目,咱们大体分为两类,一类是加钱,一类是不加钱。那么之后在在其中一个类中写出执行逻辑即可。
69.3 代码演示:
//牛牛快递
int main() {float a;char b;cin >> a >> b;int money = 0;//总体思路分为两个大方向,加急以及不加急if (b == 'y') {if (a <= 1) {cout << 25 << endl;}else {//单独计算超出1的那部分while (a - 1 > 1) {money++;a--;}money += 26;cout << money << endl;}}else {if (a <= 1) {cout << 20 << endl;}else {//单独计算超出1的那部分while (a - 1 > 1) {money++;a--;}money += 21;cout << money << endl;}}
}
ok,本篇完.....