Day1算法训练(数字统计,两个数组的交集,点击消除)
1.数字统计

解法:枚举+数字拆分(不断地%10,再除以10),只要注意一下用一个中间变量就好了
就是枚举从L到R的所有整数,对其中的每个整数进行拆分,统计每一位2的个数
#include <iostream>
using namespace std;
int main()
{int L = 0, R = 0;cin >> L >> R;int i = 0;int ret = 0;for (i = L; i <= R; i++){int tmp = i;//本题需要注意的就是这里的i是要挨个遍历的;//因此我们不能随便吧i传进去,去取i的每一位,要借助中间变量while (tmp){if (tmp % 10 == 2)ret++;tmp /= 10;}}cout << ret << endl;return 0;
}
2.两个数组的交集

正解:题意与题目一样,就是求这两个数组的交集即可。但是有一点歧义:如果两个数组中有多个元素相等的haul,返回一个元素即可。(eg:{2,2,2}和{2,2},返回{2}即可)。我们只需要确定,遍历其中一个数组,另一个数组中是否与他拥有相同的元素即可。利用bool类型的哈希表,注意先全部初始化为false,把在nums1中出现的元素作为哈希表的下标值存为true,遍历nums2,如果该元素的作为下标的哈希值为true,说明nums1中也存在该元素,所以要push_back进我们的新vector中,同时,为了防止该元素多次出现,我们要把此元素的哈希值设为false,最后不要忘记了升序排序。
class Solution {public:bool hash[1010]={false}; vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {vector<int>ret;for(auto i:nums1){hash[i]=true;} for(auto e:nums2){if(hash[e]){ret.push_back(e);hash[e]=false;}}sort(ret.begin(),ret.end());return ret;
}
};
我的思路:先把两个数组进行一下升序排序,遍历其中一个数组,另一个数组在内部与之比较,只要考虑大于小于和等于三种情况即可。
1.我没有想到能够借助哈希表来作为类似‘中间变量’的东西来解决此问题。哈希表的相关概念及立体需要回顾
2.我一直在纠结两个数组的长度对于遍历是否有影响,其实是没有影响的,要理清思路。
3.我有考虑到歧义问题,但是没有深究,23.5%通过后一直在纠结逻辑问题,答题逻辑是没有问题的,反而没有想到歧义这个问题。如果涉及到歧义,那我的方法就更麻烦了。
3.点击消除

题意:必须是相邻且相同的两个字母才能消除 。我们判断的是一个动态的消除过程,我们要判断在每次消除后的序列里是否存在相邻且相同的字母。(题意都读出来了)
正解:与‘括号匹配’题型相似。利用栈的数据结构来解决此类问题。遍历字符串,与栈顶元素作比较,如果不相同,则入栈,如果相同,则栈顶元素出栈。仅需遍历一遍字符串,元素最多进栈出栈n次,所以空间复杂度和时间复杂度都是O(n)。一个细节问题:用可变长的数组来模拟栈结构,在string 中可以尾插和尾删。why?因为如果用栈,最后出栈时要得到我们所要求的字符串是一个逆序的过程,还需要一个reverse的过程,不如直接用string直接输出。
#include <iostream>
#include <string>
using namespace std;
int main()
{string s1;cin>>s1;string s2;for(auto e:s1){if(s2.size()&&s2.back()==e){s2.pop_back();//注意出战的时候战力一定要有元素,且pop()里不需要加东西}else{s2.push_back(e);//或者写成s2+=e也可以}}if(!s2.empty())cout<<s2;//s.empty():s为空则返回true,else cout<<0;//或者上述两行可以合并写成:cout<<(s2.size()==0?"0":s2)<<endl;return 0;
}
我的思路:我就完全暴力解题,结果超时了。
4.小结
一定要善于利用学过的各种数据结构和stl库,以及熟练使用各种库的函数用法。下去之后复习哈希表和栈的数据结构的内容。
