第一题:数组能形成多少数对
思路:对数组先进行排序,将能构成数对的数区分并统计数量,然后再遍历一次统计剩下的数量,最后返回
class Solution {
public:
vector<int> numberOfPairs(vector<int>& nums) {
sort(nums.begin(),nums.end());
int res=0,count=0;
for(int i=0;i<nums.size()-1;i++){
if(nums[i]==nums[i+1]){
nums[i]=-1;
nums[i+1]=-1;
res++;
}
}
for(auto k:nums){
if(k!=-1) count++;
}
return {res,count};
}
};
第二题:数位和相等数对的最大和
思路:用unordered_map来实现,将对应原数组元素的数位和作为key,然后把数位和相同的元素相加,最后返回最大值,如果没有相同的元素则返回-1(借鉴了组长的写法,stl的使用还有很大一部分不会,继续学习!)
class Solution {
public:
int maximumSum(vector<int>& nums) {
unordered_map<int,int> mp;
int res=-1;
for(auto k:nums){
int s=k,num=0;
while(s){
num+=s%10;
s/=10;
}
if(mp.count(num)) res=max(res,k+mp[num]);//count函数可以判断集合中有没有数位和相同的num
mp[num]=max(mp[num],k);//更新一下最大值,因为所求和为最大和
}
return res;
}
};
第三题: 裁剪数字后查询第 K 小的数字
思路:用pair绑定,对nums中的字符串进行排序,然后储存返回即可
class Solution {
public:
vector<int> smallestTrimmedNumbers(vector<string>& nums, vector<vector<int>>& queries) {
typedef pair<string,int> PLL;
int n=nums.size(),m=nums[0].size(),t=queries.size();
vector<int> ans(t);
int k=0;
while(t--){
vector<PLL> res;
for(int i=0;i<n;i++){
string tmp=nums[i].substr(m-queries[k][1],queries[k][1]);//substr的两种用法
res.push_back({tmp,i});
//push_back是在末尾再添加,如果给res定义为vector<PLL>res(n)就会出现错误,因为前n个都是0
}
sort(res.begin(),res.end());
ans[k]=res[queries[k][0]-1].second;
k++;
}
return ans;
}
};
第四题:使数组可以被整除的最少删除次数
思路:对nums进行排序,再来遍历nums中的元素能否整出numsDivide的所有元素,统计不能将目标数组整除的元素个数直到出现可以整除的元素时返回即可,但暴力来时间复杂度为O(n^2),最后几个数据过不了。改用先找出目标数组的最大公约数,其他约数一定可以整除最大公约数,然后再看原数组能否有将其整除元素返回即可
class Solution {
public:
int gcd(int a,int b){
return b ? gcd(b,a%b) : a;
}//求两个数的最大公约数的模板函数
int minOperations(vector<int>& nums, vector<int>& numsDivide) {
sort(nums.begin(),nums.end());
int res=0;
int tmp=0;
for(auto k:numsDivide) tmp=gcd(k,tmp);//找到目标数组中的最大公约数
for(auto k:nums){
if(tmp%k==0) break;
else res++;
}
if(res==nums.size()) return -1;
else return res;
}
};
//超时代码
/*
class Solution {
public:
int minOperations(vector<int>& nums, vector<int>& numsDivide) {
sort(nums.begin(),nums.end());
int res=0,k=0,u=nums.size();
while(u--){
bool t=true;
for(int i=0;i<numsDivide.size();i++){
if(numsDivide[i]%nums[k]!=0){
t=false;
break;
}
}
if(t) return res;
else {
res++;
k++;
}
}
return -1;
}
};
*/