第一题
解题思路:
使用unordered_map<int,int>把整数和该整数在数组中出现的次数关联起来
class Solution
{
public:
vector<int> numberOfPairs(vector<int>& nums)
{
unordered_map<int,int> m;
//<key,value>:key表示整数,value表示该整数在数组中出现的次数
for(auto n:nums)//遍历nums,往m中存入数据
m[n]++;
int ans0=0,ans1=0;
for(auto [i1,i2]:m)//遍历m,得ans0
ans0+=i2/2;
ans1=nums.size()-ans0*2;
return vector<int>{ans0,ans1};
}
};
第二题
解题思路:
写一个GetSum()函数用于求数位和
使用map<int,vector<int> >把数位和与对应数位和的正整数的下标值关联起来
技巧性步骤是提前把数组排序
class Solution
{
public:
int GetSum(int num)//求数位和函数
{
int sum=0;
while(num>0)
{
sum+=num%10;
num/=10;
}
return sum;
}
int maximumSum(vector<int>& nums)
{
map<int,vector<int> > M;
//key代表数位和;value代表对应数位和的正整数的下标值,使用vector<int>存储
sort(nums.begin(),nums.end());
//提前把数组排序,下标值越大对应的正整数越大
for(int i=0;i<nums.size();i++)
M[GetSum(nums[i])].push_back(i);
//越后被存入的下标值越大
int ma_x=-1;
for(int i=0;i<=81;i++)//由题设可知数位和最小为0,最大为81
if(M[i].size()>=2)
{
int temp=nums[ M[i][M[i].size()-1] ] + nums[ M[i][M[i].size()-2] ];
//为了使得和尽可能大,所以选择最后两个下标(该数位和条件下的最大的两个下标)对应的正整数相加
if(temp>ma_x) ma_x=temp;
}
return ma_x;
}
};
第三题
解题思路:
两个字符串比较大小的规则是从左往右逐个比较各自相同位置的字符,
字符相同则比较下一个位置字符,直到出现不同字符,字符大字符串就大,
若有一个字符串直到结束也没有出现不同字符,就认为较长的字符串较大。
根据该规则,相同长度的数字字符串大小比较的结果 和 数字大小比较的结果 相同
使用pair<string,int>把 裁剪后的字符串 和 字符串对应的下标值 关联起来
class Solution
{
public:
vector<int> smallestTrimmedNumbers(vector<string>& nums, vector<vector<int>>& queries)
{
int l=nums[0].size();//l为字符串长度(每个字符串长度相等)
vector<int> answer;//数组answer存储每次查询的结果
for(int i=0;i<queries.size();i++)//处理每次查询
{
int k=queries[i][0];
int trim=queries[i][1];
vector< pair<string,int> > A(nums.size());
//first存储裁剪后的字符串,second存储字符串对应的下标值,pair将两者关联起来
for(int j=0;j<nums.size();j++)//对于每次查询都需要裁剪所有字符串
{
string s=nums[j].substr(l-trim);//注意substr的使用
A[j]=make_pair(s,j);//注意make_pair的使用
}
sort(A.begin(),A.end());
//需要熟悉字符串比大小的规则
//sort函数默认对pair中的first从小到大排序
//若first相等,则默认对pair中的second从小到大排序
answer.push_back(A[k-1].second);
}
return answer;
}
};
第四题
解题思路:
使用gcd()函数求numsDivide数组中所有正整数的最大公约数ma_x
那么,ma_x以及ma_x的因子就是所有的可以整除numsDivide数组中所有正整数的数
关键是找出ma_x以及ma_x的因子中的存在nums数组中的最小值,从而确定最少删除次数
class Solution
{
public:
int minOperations(vector<int>& nums, vector<int>& numsDivide)
{
int ma_x=0;
for(int i=0;i<numsDivide.size();i++)
ma_x=gcd(ma_x,numsDivide[i]);
//经过此轮for循环后,ma_x即为numsDivide数组中所有正整数的最大公约数
sort(nums.begin(),nums.end());
//为了删除次数尽可能少,应当选择尽可能小的数作为除数,所以提前排序nums数组
int ans=-1;
for(int i=0;i<nums.size();i++)
if(ma_x % nums[i] == 0)//nums[i]就是符合题目要求的除数
{
ans=i;//比nums[i]小的数应当全部被删除
break;
}
return ans;
}
};