1814. 统计一个数组中好对子的数目
给你一个数组 nums ,数组中只包含非负整数。定义 rev(x) 的值为将整数 x 各个数字位反转得到的结果。比方说 rev(123) = 321 , rev(120) = 21 。我们称满足下面条件的下标对 (i, j) 是 好的 :
0 <= i < j < nums.length
nums[i] + rev(nums[j]) == nums[j] + rev(nums[i])
请你返回好下标对的数目。由于结果可能会很大,请将结果对 109 + 7 取余 后返回。
每日一题
我们可以发现
nums[i]位数==num[j]的位数
那这个必是好对子
或者
i和j都满足
nums[i]==rev(nums[i])
啊不对上面的都不正确
重要的不是优化怎么判断是不是好对子
而是优化对子之间的关系
比如
a和b是好对子
b和c是好对子
a和c是好对子吗?
答案是肯定的,推导:
a+rev(b)=rev(a)+b
rev(b)+c=rec( c)+b
易得
a+rev(c)=rev(a)+c
或许我们可以用并查集?
比方说一组好对子有n个数字
那么就有(n-1)*n/2对
统计个数
建立一个map表,匹配不到就加进去,匹配到了数量就+1
失算了
还可以优化成
a-rev(a)
值相等就ok
class Solution {
public:
int rev(int x)
{
int ans=0;
cout<<x<<endl;
while(x)
{
int t=x%10;
ans=ans*10+t;
x/=10;
}
cout<<"---"<<ans<<endl;
return ans;
}
int countNicePairs(vector<int>& nums) {
const int mod=1e9+7;
int n=nums.size();
int ans=0;
map<int,int>mp;
map<int,int>mk;
for(int i:nums)
{
int t;
if(mk[i])//计算过了
t=mk[i];
else
{
mk[i]=t=i-rev(i);
}
if(mp[t])
{
ans+=mp[t];
ans%=mod;
}
mp[t]++;
}
return ans;
}
};
这题这是唯一解啊
如果不按a-rev(a)优化的话超时了。。
发现今天的剑指offer计划的题之前也写了
写些其他的吧
剑指 Offer 39. 数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
三个方法都学习了
哈希方法
class Solution {
public:
int majorityElement(vector<int>& nums) {
int n=nums.size()/2;
map<int,int>mp;
for(int i:nums)
{
if(++mp[i]>n)
return i;
}
return 0;
}
};
排序方法
class Solution {
public:
int majorityElement(vector<int>& nums) {
int n=nums.size();
sort(nums.begin(),nums.end());
return nums[n/2];
}
};
摩尔投票
class Solution {
public:
int majorityElement(vector<int>& nums) {
int votes=0,x=0;
for(int i:nums)
{
if(votes==0)
x=i;
votes+= i==x?1:-1;
}
return x;
}
};