242.有效的字母异位词
题目:给定两个字符串 s
和 t
,编写一个函数来判断 t
是否是 s
的字母异位词。
注意:若 s
和 t
中每个字符出现的次数都相同,则称 s
和 t
互为字母异位词。
思路:哈希表,用unordered_map
(底层是哈希表实现)存储字母及其出现次数。由于仅是字母,其实开一个26长度的数组也行。
通过代码:
class Solution {
public:
bool isAnagram(string s, string t) {
unordered_map<char, int> map;
for(int i = 0; i < s.length(); i++)
map[s[i]] += 1;
for(int i = 0; i < t.length(); i++)
map[t[i]] -= 1;
for(auto c: map)
{
if(c.second != 0)
return false;
}
return true;
}
};
349. 两个数组的交集
题目:给定两个数组 nums1
和 nums2
,返回 它们的交集。输出结果中的每个元素一定是唯一 的。我们可以不考虑输出结果的顺序 。
思路:将其中一个数组的元素全部放进哈希表里,遍历第二个数组,查询是否在表里出现。
通过代码:
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result;
unordered_set<int> s(nums1.begin(), nums1.end());
for(int i = 0; i < nums2.size(); i++)
{
if(s.find(nums2[i]) != s.end())
result.insert(nums2[i]);
}
return vector<int>(result.begin(), result.end());
}
};
202.快乐数
题目:编写一个算法来判断一个数 n
是不是快乐数。「快乐数」 定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n
是 快乐数 就返回 true
;不是,则返回 false
。
思路:能出现无限循环的情况一定是平方和会重复出现,用一个哈希表存一下就行,如果能在表里查到,说明会一直循环下去,不是快乐数。
通过代码:
class Solution {
public:
int happy(int n)
{
int res = 0;
while(n)
{
res += pow(n % 10, 2);
n /= 10;
}
return res;
}
bool isHappy(int n) {
unordered_set<int> hash;
while(1)
{
int hp = happy(n);
if(hp == 1)
return true;
if(hash.find(hp) != hash.end())
return false;
else
hash.insert(hp);
n = hp;
}
}
};
1. 两数之和
题目:给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。
思路:用unordered_map把已经遍历过的数据存起来,key是数组的值,value是对应的索引。遍历的时候在表里查找target-当前值
,若存在即可返回。
通过代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
for(int i = 0; i < nums.size(); i++)
{
auto iter = m.find(target - nums[i]);
if(iter != m.end())
return vector<int>{iter -> second, i};
m.insert(make_pair(nums[i], i));
}
return vector<int>{};
}
};
454.四数相加II
题目:给你四个整数数组 nums1
、nums2
、nums3
和 nums4
,数组长度都是 n
,请你计算有多少个元组 (i, j, k, l)
能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
思路:nums1和nums2一组,用一个unordered_map存放它们的和及其次数;nums3和nums4一组,在map里查找-(nums3[i]+nums4[j])
即可。
通过代码:
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int cnt = 0;
unordered_map<int, int> ab;
for(int i = 0; i < nums1.size(); i++)
for(int j = 0; j < nums2.size(); j++)
ab[nums1[i] + nums2[j]] += 1;
for(int i = 0; i< nums3.size(); i++)
for(int j = 0; j < nums4.size(); j++)
{
auto iter = ab.find(-(nums3[i] + nums4[j]));
if(iter != ab.end())
cnt += iter -> second;
}
return cnt;
}
};
383. 赎金信
题目:给你两个字符串:ransomNote
和 magazine
,判断 ransomNote
能不能由 magazine
里面的字符构成。如果可以,返回 true
;否则返回 false
。magazine
中的每个字符只能在 ransomNote
中使用一次。
思路:用一个map记录有哪些字符及其出现次数。
通过代码:
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
unordered_map<char, int> map;
for(char c : magazine)
map[c] +=1;
for(char c : ransomNote)
{
if(map.find(c) == map.end())
return false;
map[c]--;
if(map[c] < 0)
return false;
}
return true;
}
};
15.三数之和
题目:给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
思路:排序之后用一个指针确定第一个数的位置,剩下两个数再用双指针。
通过代码:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size(); i++)
{
if(i > 0 && nums[i] == nums[i-1])
continue;
int target = -nums[i], right = nums.size() - 1;
for(int left = i + 1; left < right; left++)
{
if(left > i + 1 && nums[left] == nums[left - 1])
continue;
while(left < right && nums[left] + nums[right] > target)
{
right--;
}
if(left == right)
break;
if(nums[left] + nums[right] == target)
result.push_back({nums[i], nums[left], nums[right]});
}
}
return result;
}
};
18.四数之和
题目:给你一个由 n
个整数组成的数组 nums
,和一个目标值 target
。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]]
(若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a
、b
、c
和d
互不相同nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
思路:和三数之和类似,加一重循环即可。
通过代码:
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
if(nums.size() < 4)
return result;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size() - 3; i++)
{
if(i > 0 && nums[i] == nums[i - 1])
continue;
for(int j = i + 1; j < nums.size() - 2; j++)
{
if(j > i + 1 && nums[j] == nums[j - 1])
continue;
long long newtarget = (long long)target - nums[i] - nums[j];
int right = nums.size() - 1;
for(int left = j + 1; left < right; left++)
{
if(left > j + 1 && nums[left] == nums[left - 1])
continue;
while(left < right && nums[left] + nums[right] > newtarget)
right--;
if(left == right)
break;
if(nums[left] + nums[right] == newtarget)
result.push_back({nums[i], nums[j], nums[left], nums[right]});
}
}
}
return result;
}
};