202 快乐数
题目理解
何为快乐数,一个正整数,每次将该数替换为各个位置数字的平方和,循环直到该数变为1,则为快乐数,若无限循环变不为1,则不是快乐数。
思路
题目说了可能会无限循环变不为1,则说明在每次循环的过程中,可能会存在平方和在前一时刻已经出现过,这样就会陷入无限循环,说明不是快乐数。
那么问题就变成了:①求平方和②判断平方和是否出现过。
判断的方法可以使用哈希数组,也可使用快慢指针。
代码
哈希数组
class Solution {
public:
int getSum(int n) {
int sum = 0;
while (n) {
int a = n % 10;
n /= 10;
sum += a * a;
}
return sum;
}
bool isHappy(int n) {
unordered_set<int> s;
int num = n;
while (num != 1) {
s.insert(num);
num = getSum(num);
if (s.find(num) != s.end())
return false;
}
return true;
}
};
快慢指针
class Solution {
public:
int getSum(int n) {
int sum = 0;
while (n) {
int a = n % 10;
n /= 10;
sum += a * a;
}
return sum;
}
bool isHappy(int n) {
int slow = n, fast = n;
do {
slow = getSum(slow);
fast = getSum(fast);
fast = getSum(fast);
} while(slow != fast);
if (slow == 1)
return true;
return false;
}
};
1 两数之和
思路
要寻找和为target的两个数,即遍历数组,寻找值为i ,target-i这两个数的下标即可,使用哈希表查找元素时间复杂度仅为O(1)。
代码
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> num;
for(int i = 0;i < nums.size();i++) {
if(num.find(target - nums[i]) != num.end()) {//避免数组同一元素使用两次,因此先进行判断再添加到哈希表中。
return {i,num[target - nums[i]]};
}
num.insert({nums[i],i});
}
return {};
}
};
454 四数相加 Ⅱ
思路
将四个数组分为两部分,一部分为A+B,存在哈希表中(key为两数之和,value为此和出现次数),另一部分为C+D,则判断四数之和是否为0,变为了寻找哈希表中,0-(C+D)是否存在。
代码
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
unordered_map<int,int> sum2;
int count=0;
for(auto a:A)
for(auto b:B)
++sum2[a+b];
for(auto c:C)
for(auto d:D) {
if(sum2[0-(c+d)]>0)
{
count+=sum2[0-(c+d)];
}
}
return count;
}
};
383 赎金信
思路
寻找magazine是否包含ransom,而且两个字符串均由小写字母构成,因此可以用一个长度为26的数组来记录magazine中字符出现的子数,遍历ransom,判断各字符在哈希表中的值即可。
代码
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int c[26] = {0};
for (auto i : magazine) {
++c[i - 'a'];
}
for (auto i : ransomNote) {
if (c[i - 'a'] > 0)
--c[i - 'a'];
else return false;
}
return true;
}
};