代码随想录算法训练营第六天 | LeetCode242有效的字母异位词 、LeetCode349两个数组的交集、LeetCode202快乐数、LeetCode1两数之和
时长:大约2小时
242. Valid Anagram
Given two strings s and t, return true if t is an anagram of s, and false otherwise.
An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
Example 1:
Input: s = "anagram", t = "nagaram"
Output: true
Example 2:
Input: s = "rat", t = "car"
Output: false
Constraints:
1 <= s.length, t.length <= 5 * 104
s and t consist of lowercase English letters.
Follow up: What if the inputs contain Unicode characters? How would you adapt your solution to such a case?
解题思路:
先判读字符串长度,不一样直接false
对s中的字符进行统计,基于unordered_map,key是字符,value是字频
根据t中的字符对unordered_map进行修改,t中每出现一个词,则哈希表中对应字频减1
若出现
t中的字符在unordered_map中没有
unordered_map中字频减到<0了,则返回false
否则返回true
需要注意的要点:
这一方法需要先对字符串长度进行判读
否则需要对更新后的unordered_map在检查一遍是不是所有元素为0
// 我的实现
class Solution {
public:
bool isAnagram(string s, string t) {
if (s.length() != t.length()) {
return false;
}
unordered_map<char, int> char2count;
for(int i = 0; i < s.length(); ++ i) {
auto it = char2count.find(s[i]);
if(it == char2count.end()) {
char2count[s[i]] = 1;
}
else {
char2count[s[i]] ++;
}
}
for(int i = 0; i < t.length(); ++ i) {
auto it = char2count.find(t[i]);
if(it == char2count.end()) {
return false;
}
else {
char2count[t[i]] --;
if (char2count[t[i]] < 0) {
return false;
}
}
}
return true;
}
};
// carl的方法
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26] = {0};
for (int i = 0; i < s.size(); i++) {
// 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
record[s[i] - 'a']++;
}
for (int i = 0; i < t.size(); i++) {
record[t[i] - 'a']--;
}
for (int i = 0; i < 26; i++) {
if (record[i] != 0) {
// record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
return false;
}
}
// record数组所有元素都为零0,说明字符串s和t是字母异位词
return true;
}
};
349. Intersection of Two Arrays
Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must be unique and you may return the result in any order.
Example 1:
Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2]
Example 2:
Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
Output: [9,4]
Explanation: [4,9] is also accepted.
Constraints:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
解题思路:
先把nums1放入set1中
新建一个存放结构的set的res
遍历nums2,在set1中的元素加入res
需要注意的要点:
vector和set的转换操作
unordered_set<int> nums_set(nums1.begin(), nums1.end());
遍历数组元素
for (int num : nums2) {
...
}
// 我的实现
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> uset1;
unordered_set<int> uset2;
for(int i = 0; i < nums1.size(); ++i) {
uset1.emplace(nums1[i]);
}
for (int i = 0; i < nums2.size(); ++ i) {
if(uset1.find(nums2[i]) != uset1.end()) {
uset2.emplace(nums2[i]);
}
}
vector<int> res(uset2.begin(), uset2.end());
return res;
}
};
// carl
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重
unordered_set<int> nums_set(nums1.begin(), nums1.end());
for (int num : nums2) {
// 发现nums2的元素 在nums_set里又出现过
if (nums_set.find(num) != nums_set.end()) {
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
};
202. Happy Number
Write an algorithm to determine if a number n is happy.
A happy number is a number defined by the following process:
Starting with any positive integer, replace the number by the sum of the squares of its digits.
Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1.
Those numbers for which this process ends in 1 are happy.
Return true if n is a happy number, and false if not.
Example 1:
Input: n = 19
Output: true
Explanation:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
Example 2:
Input: n = 2
Output: false
Constraints:
1 <= n <= 231 - 1
解题思路:
关键在于一点:题目中说会无限循环,说明平方和会重复出现,因此只要利用哈希表存储出现过的结果,再次遇到出现过的结果就不是快乐数
需要注意的要点:
关键在于想到无限循环对应数字重复出现吧
// 我的实现
class Solution {
public:
bool isHappy(int n) {
if(n == 1) {
return true;
}
unordered_set<int> uset;
int sum;
while(1) {
sum = getSquareSum(n);
if (sum == 1) {
return true;
}
else {
if (uset.find(sum) == uset.end()) {
uset.emplace(sum);
n = sum;
}
else {
return false;
}
}
}
}
int getSquareSum(int n) {
int sum = 0;
while (n > 0) {
int bit = n % 10;
n /= 10;
sum += pow(bit, 2);
}
return sum;
}
};
//carl
class Solution {
public:
// 取数值各个位上的单数之和
int getSum(int n) {
int sum = 0;
while (n) {
sum += (n % 10) * (n % 10);
n /= 10;
}
return sum;
}
bool isHappy(int n) {
unordered_set<int> set;
while(1) {
int sum = getSum(n);
if (sum == 1) {
return true;
}
// 如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
if (set.find(sum) != set.end()) {
return false;
} else {
set.insert(sum);
}
n = sum;
}
}
};
1. Two Sum
You may assume that each input would have exactly one solution, and you may not use the same element twice.
You can return the answer in any order.
Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
Example 2:
Input: nums = [3,2,4], target = 6
Output: [1,2]
Example 3:
Input: nums = [3,3], target = 6
Output: [0,1]
Constraints:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
Only one valid answer exists.
Follow-up: Can you come up with an algorithm that is less than O(n2) time complexity?
解题思路:
采用unordered_map,key是值,value是数组下标
对数组遍历:
先查看在unordered_map中能不能找到数与当前数之和为target
找到即返回
否则,将当前的数和下标计入unordered_map
需要注意的要点:
由于先查在存,因此example3的设置也没有问题,第二个3存入之前会找到第一个3
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> umap;
for(int i = 0; i < nums.size(); ++ i) {
int left = target - nums[i];
auto it = umap.find(left);
if (it != umap.end()) {
return {i, it->second};
}
umap.emplace(make_pair(nums[i], i));
}
return {};
}
};
//carl
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 {};
}
};
声明:
文章中LeetCode的题目来自LeetCode官网:https://leetcode.cn/problems