leetcode242 有效的字母异位词
分析
简单来说判断两个字符串中出现的字母次数是否一致
首先明确一点我们采用暴力遍历的方法当然能做,但是效率太低下了
- 字母的ascill码连续,我们采取一个哈希函数将字母映射的数组的下标对应起来
- 有该字母加一
- 另外一个字符串有该字母减一,因此后面判断数组是否都为0即可
代码详解
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26] = {0};
for(int i = 0; i<s.size(); i++) //将s字符串映射到数组上
{
record[s[i] - 'a']++;
}
for (int i = 0; i < t.size(); i++) // 将t字符串对应字母进行减1
{
record[t[i] - 'a']--;
}
for (int i = 0; i < 26; i++) { // 遍历record数组 判断是否为0
if (record[i] != 0) {
return false;
}
}
return true;
}
};
leetcode 349 两个数组的交集
学到了什么
- 一堆里面查找用哈希,这个里面用到的是不排序的更快
- end是指向最后一个元素的下一个即null
- 查找想hash!!!
代码实现
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set;
unordered_set<int> nums1_set(nums1.begin(), nums1.end());
for(int i=0; i<nums2.size(); i++)
{
if(nums1_set.find(nums2[i]) != nums1_set.end()){
result_set.insert(nums2[i]);
}
}
return vector<int> (result_set.begin(), result_set.end());
}
};
leetcode 202 快乐数
学到什么
错误想法
我刚刚开始想的是取到每一位进行求平方和 然后看循环吗 但是对于无限循环理解不够(出现第二次循环即可退出)
正确思路
关于取各个数位的函数
int getsum(int n){
int sum = 0;
while(n){ //n为0即退出
sum += (n % 10) * (n % 10); //先不断的取余即当前的最后一位
n = n /10; // 除以10进行后移一位 再次进行上述的操作
}
return sum;
}
无限循环 可以定义一个unordered的集合然后判断是否在此集合中出现过
代码实现
class Solution {
public:
// 取每个位上的数字
int getsum(int n){
int sum = 0;
while(n){
sum += (n % 10) * (n % 10);
n = n /10;
}
return sum;
}
bool isHappy(int n) {
unordered_set<int> result;
while(1){
int sum = getsum(n);
if(sum == 1){
return true;
}
if(result.find(sum) != result.end()){
return false; // 说明找到重复的
}else{
result.insert(sum);
}
n = sum;
}
}
};
leetcode1. 两数之和
第一次的做法(暴力遍历)
我第一次做没想到map来做,采用的暴力法即两次的for循环
具体代码
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> v = {0, 0};
for (int i = 0; i < nums.size(); i++){
int a = target - nums[i];
v[0] = i;
for (int j = i + 1; j < nums.size(); j++){
if(a == nums[j]){
v[1] = j;
break;
}
}
if(((nums[i]+nums[v[1]])==target) && (i!=v[1])){
break;
}
}
return v;
}
};
暴力法与map的比较
其实map就是把其中一层的for循环用map实现,即查找另外一个元素的过程,所以时间复杂度就只有O(n)
map方法的代码实现(摘录于代码随想录)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
std::unordered_map <int,int> map;
for(int i = 0; i < nums.size(); i++) {
// 遍历当前元素,并在map中寻找是否有匹配的key
auto iter = map.find(target - nums[i]);
if(iter != map.end()) {
return {iter->second, i};
}
// 如果没找到匹配对,就把访问过的元素和下标加入到map中
map.insert(pair<int, int>(nums[i], i));
}
return {};
}
};
个人总结
学到的概括来讲就是采用普通方法需要遍历搜索的时候,那么这个过程可以交给hash来实现(少了一层循环)!!!