**
383. 赎金信
**
思路分析:
其实大体上和上一题的思路是差不多的,但是这回的题目不能直接照抄上面的代码,因为如果照抄上面的代码会因为masazine中存在其他字符而导致无法通过最后的判断record元素值是否为来返回false和true。但其实也不复杂,我们只需要再需要一个HashSet来存一下ransomNote中的元素,然后在后面比对时进行判断即可,代码如下:
class Solution {
public bool canConstruct(String ransomNote, String magazine) {
//还是用之前的老方法,不过这里需要加个HashSet来帮忙判断
int record[26] = {0};
for(char c : ransomNote.toCharArray()){
record[c - 'a'] ++;
}
for(char c : magazine.toCharArray()){
record[c - 'a'] --;
}
for(int c : record){
if(c > 0) return false;
}
return true;
}
}
**
49. 字母异位词分组
**
思路分析:
一开始没啥思路,囿于了前面两题的解题思路,妈的。
看了题解之后发现还蛮简单的,其实我们可以用一个HashMap来进行记录,map的key值为一个该组字母异位词的标志字符串,而怎么拿到这个标志字符串我们可以通过排序的方式来拿到,比如nat和tan是一组字母异位词,那么我们只要将其中任意的字符串比如nat进行排序得到ant,不难发现tan排序过后也是ant,我们只需要将排序过后的字符串作为key键存入map中,然后将所有符合这个排序规则的字符串都存入map中的value就可以了。
class Solution{
public:
vector<vector<int>> groupana(vector<string>&strs){
vector<vector<string>>res;
unordered_map<string,vector<string>>hash;
for(string str:strs){ //遍历每个单词
string tmp = str;
sort(tmp.begin(),tmp.end()); //对每个单词字母排序
hash[tmp].push_back(str);//将排序后的单词作为key,原始单词作为value
}
for(auto&vec:hash){
res.push_back(vec.second); //遍历字典,将字典的value加入到列表中
}
return rec;
}
};
**
438. 找到字符串中所有字母异位词
**
class Solution{
public:
vector<int>findang(string s, string p){
int n= s.size();
int m=p.size();
if(n<m) return vector<int>(); //s串小于p串
vrector<int>ans;
vector<int>cnt1(26),cnt(26);
for(int i=0;i<p.size();i++){
++cnt1[p[i]-'a']; //将字符映射到数组中
++cnt2[s[i]-'a'];
}
if(cnt1==cnt2) ans.push_back(0); //如果一开始滑动窗口和字符串p相等则将下标为0输入
//如果不相等,则将滑动窗口向后每次移动一位
for(int i=m;i<s.size();i++){
++cnt2[s[i]-'a']; //向右移一位,给滑动窗口增加新元素
--cnt2[s[i-m]-'a']; //将左边界元素移除,向前移动,将原本的第一位移除
if(cnt1==cnt2) ans,push_backI(i-m+1);//如果数组相同就是字符出现的字数是相同的则将初始位置输入ans中
}
return ans;
}
}
**
349. 两个数组的交集
**
class Solution{
public:
vector<int> intersecdtion(vector<int>&nums1,vector<int>&nums2){
unordered_map<int> result_set;
unordered_map<int> nums_set(nums1.begin(),nums1.end());
for(int num:nums2){
if (nums_set.find(num)!=nums_set.end()){
result_set.insert(num);
}
}
reutrn vector<int>(result_set.begin(),result_set.end());
}
}
**
350.两个数组的交集 II
**
思路描述:
题目意思是说由于同一个数字在两个数组中都可能出现多次,因此需要用哈希表存储每个数字出现的次数。对于一个数字,其在交集中出现的次数等于该数字在两个数组中出现次数的最小值。
那么用哈希表法如下:
首先遍历第一个数组,并在哈希表中记录第一个数组中的每个数字以及对应出现的次数,然后遍历第二个数组,对于第二个数组中的每个数字,如果在哈希表中存在这个数字,则将该数字添加到答案,并减少哈希表中该数字出现的次数。
class Solution{
public:
vector<int> banaid(vector<int>nums1,vector<int>nums2){
unordered_map<int, int>m;
for(int i=0;i<nums1.soze();i++){
++m[nums1[i]]; //将数组1中的每个值加入到字典中
}
vector<int>intersetipon; //结果空数组
for(int num:nums2){//遍历数组2
if(m.count(num)){ //看字典中是否存在数组2的元素
intersecdtion.push_back(num); //将字典中存在的值加入结果数组
--m[num];//字典中减去相应的value;
if(m[num]==0){ //字典value等于0的时候删除该key
m.earse(num);
}
}
}
return intersecdtion;
}
}
**
202. 快乐数
**
class Solution{
public:
int getSum(int n){
int sum=0;
//首先将计算每个数的位数上的乘方的和
while(n){
sum+=(n%10)*(n%10);
n/=10;
}
reuturn sum;
}
bool isHappy(int n){
unordered_map<int> set;
while(1){
//如果和为1则为快乐数返回
int sum==getSum(n);
if(sum==1){
reutrn true;
}
//如果在哈希表中已经出现过就表示不是快乐数陷入无限循环则返回错误
if(set.find(sum)!=set.end()){
return false;
}
else{
//将sum加入哈希表
set.insert(sum);
}
n=sum;
}
}
}
1. 两数之和
class Solution{
public vector<int> twosum(vector<int>&nums,int target){
vector<int>result(2); //结果集
unordered_map<int,int>m; //字典
for(int i=0;i<nums.size();i++){
if(m.find(target-nums[i])!=m.end()){ //差值在字典中发现
result.push_back(i); //返回第一个下标
result.push_back(m(nums[i]));//返回第二个下标
}
m.insert(pair<int,int>(nums[i],i)); //将每个值加入key,将每个下标加入value
}
reuturn {};
}
}
- 四数相加 ||
class Solution{
public:
int foursumcount(vector<int>&A,vector<int>&B,vector<int>&C,vector<int>&D){
unordered_map<int, int>m;
for(int a: A){
for(int b:B){
m[a+b]++;
}
}
int count=0;
for(int c:C){
for(int d:D){
if(m.find(0-(c+d))!=m.end()){
count+=m[0-(c+d)];
}
}
}
return count;
}
}
- 三数之和
class Solution{
public:
vector<vector<int>>threesum(vector<int>&nums){
vector<int>result;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i++){
if(nums[i]>0) return result;
if(i>0 && nums[i]==nums[i-1]){
continue;
}
int left = i+1;
int right=nums.size()-1;
while(right>left){
if(nums[i]+nums[left]+nums[right]>0){
right--;
while(left<right && nums[right]==nums[right-1]) right--;
}
else if(nums[i]+nums[left]+nums[right]<0){
left++;
while(left<right && numsp[left]==nums[left+1] left++);
}
else{
result.push_back(vector<int>{nums[i],nums[left],nums[right]});
while(right>left && nums[right]==nums[right-1]) right--;
while(right>left && nums[left]==nums[left+1]) left++;
left++;
right--;
}
}
return result;
}
};
- 四数之和
class Solution{
public:
vector<vector<int>>foresum(vector<int>&nums,int target){
vector<vector<int>> result;
sort(nums.begin(),nums.end());
for(int k=0;k<nums.size();k++){
if(nums[k]>target && (nums[k]>=0 ||target>=0)){
break;
}
if(k>0 && nums[k]==nums[k-1]){
continue;
}
for(int i=K+1;i<nums.size();i++){
if(nums[k]+nums[i]>target && (nums[k]+nums[i]>=0 || target>=0)){
break;
}
if(i>k+1 && nums[i]==nums[i-1]){
continue;
}
int left = i+1;
int right = nums.size()-1;
while(right>left){
if(nums[k]+nums[i]>target-(nums[left]_+nums[right])){
right--;
while(left<right && nums[right]==nums[right+1]) right--;
}
else if(nums[k]+nums[i]<target-(nums[left]+nums[right])){
left++;
while(left<right && nums[left]==nums[left-1])left++;
}
else{
result.push_back(vector<int>{nums[k],nums[i],nums[left],nums[right]});
while(right>left && nums[right]==nums[right-1]) right--;
while(right>left && nums[left]==nums[left+1]) left++;
right--;
left++;
}
}
}
}
return result;
}
}