23.1.17力扣刷题

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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值