总结:
今日刷题2道,总计用时3h10mins。
迭代器的用法不够熟悉,对于表述的部分概念不够理解。同时哈希表的使用,到此 三种方法均已实现过,应该培养对于哈希表运用的敏感度(遇到求元素重复的过程就要往哈希表的方向思考)。
1. 两数之和
自己的想法:
两轮for循环求解(暴力求解)。
正确的想法:用哈希表中的map
判断元素是否在题目中出现过/某个元素是否在集合中出现过的时候,就可以用哈希法。
根据target值来判断目标元素是否遍历过。直接运用相减的方法来求值。如果将target值 减去 当前遍历的元素 等于 已经存在map中的某个元素,则可以直接得到相关值。
为什么会想到运用哈希表?
因为哈希表可以判断一个元素是否重复出现过。而在求target值判断的时候,关键就是如果用暴力法,需要依次对每个值都进行一遍循环的相加确认工作。并且遍历到一个元素后,其实可以直接通过target - 当前遍历值的方式来判断 需要的数。 但哈希表的好处就是:将某个值纳入哈希表中,到后面就可以直接判断出这个值是否在该表中出现(find() 函数的用法)。
即 判断需要的数 是否在记录的哈希表的map中出现过。
map里面的key和value分别用来存:对应的数组的值 和 下标。
这也是为什么要使用map来保存,因为要用到数组的两个性质,一个是本身的key值,一个是对应到的value。
定义的map结构如下:
std::unordered_map <int,int> map;
若最后返回的下标值是具体的个数,则使用大括号括起来。
return {map -> value, i};
具体的代码实现中,可能会单独将迭代器拿出来定义。
如:
auto iter = map.find(target - nums[i]);
定义的iter的迭代器的值,就是原有的定义的数据结构,此时如果要访问迭代器内部的值,即
iter->second
返回的就是value的对应的下标的值。
此题解答完毕,基础思路如上体所示,但是要注意的是中间蕴含的一些用法:
1.迭代器相关的用法:
可以把迭代器理解为书的书签部分,用于标记移动到的位置。
auto是迭代器所特有的格式,再用auto->member可以访问特定涉及到的迭代器的值。
通过++/--访问特定的位置。通过*iter/iter-> member来访问特定的元素。
迭代器能与find()函数搭配使用,能够判断所要找的“位置”是否真实存在。
同时,迭代器可以访问具体的元素,来获取访问到的元素位置对应的元素的具体的值。
2.std::函数中插入的解释
map.insert(pair<int, int>(nums[i], i));
强制通过pair<int, int>类型进行转化。
std::map
的 insert()
方法只接受一个参数 - 键值对对象,所以也可以直接表述为:
map.insert({nums[i], i});
键值插入的值也是先key后value。
第454题.四数相加II
自己的想法:
毫无思路。不知道要怎么固定住另外三个的值。也不清楚这中间哪里有需要排除的重复的地方,如果套用上题的现有的find()模式也没法儿做啊。
正确的做法:哈希法两两记录。A+B的大数组的和记录,再用0-(A+B)的大循环来进行记录。
整体的思路,因为其最终目的就是使得所求得的值为0并且只要求给出次数,则将四个数组划分为两组,用两层循环的方式先得到A+B的和并记录在map中。
同时运用value记录对应的值出现的次数,到最后可以用0-对应的值得到上述记录的次数。
学习map的新用法:
umap[a + b]++;
在这里把a+b的和当成对应的key,value对应次数,正好本题求次数。
即定义的value值要与答案息息相关。