Leetcode1442:形成两个异或相等数组的三元组数目

5.18 又是被异或题支配的一天


在这里插入图片描述

思路: 异或的题目最近接连出了3天的每日一题。。。几乎每次都离不开运用异或的性质:a^b =c;a^c=b.同时**0与任何数异或都等于他本身。**我们还要注意到,两个相同的数字异或等于0.这意味着:两个相同的数字与任务数异或等于它本身 a^b=a,则b等于0。反过来a与某个数异或等于她本身,那个数一定等于0
   这个题目详细的解析可以看官网题解. 思路比较巧妙。注意到就是构造数组的是时候有时候我们需要比正常的长度+1.一般这种做法有2个目的,一个是进行整体的平移,让第一位为空,这样数组可以表示为记录了当前index记录了在原来数组中index-1的数据。在dp问题中理解为空集。 当然这么做的初衷是因为dp问题需要前一个元素的参与,除非我提前设置dp[0]否则的确要多1个位置。这个题目哈希表的求解也比较巧妙。每次都是往哈希表里面记录元素,然后同时判断哈希表中是否出现过某元素用cnt.count(s[k + 1],如果出现过,证明出现s[i]=s[k+1]的情况~

方法1:二重循环

class Solution {
public:
    int countTriplets(vector<int>& arr) {
    //我们如果将下标K作为终点可以将数组区间分为3段
    //i下标之前的一段,i到j-1的一段和j到k的一段。分别叫做abc
    //要让b=c ,可得b^c必定等于0.所以 a^b^c=a^0=a
    //根据上式因为a^b^c为从0-k的异或,所以a为从0到i的异或 所以只要满足这个条件,b可以是大于a小于等c的任意
    //遍历下标i和k统计即可。 
    int n=arr.size();
    vector<int> dp(n+1);
    for(int i=0; i<n;i++)
        dp[i+1]=dp[i]^arr[i]; //dp记录到这个下标之前的这段异或 能到---dp[n]
    int ans=0;
    for(int i=0;i<n;i++){
        for(int k=i+1; k<n; k++){
            if(dp[i]==dp[k+1])
               ans+=k-i;
        }
    }
    return ans;
    }
};

方法3:一重循环

class Solution {
public:
    int countTriplets(vector<int> &arr) {
        int n = arr.size();
        vector<int> s(n + 1);
        for (int i = 0; i < n; ++i) {
            s[i + 1] = s[i] ^ arr[i];
        }
        unordered_map<int, int> cnt, total;
        int ans = 0;
        for (int k = 0; k < n; ++k) {
            if (cnt.count(s[k + 1])) {
                ans += cnt[s[k + 1]] * k - total[s[k + 1]];
            }
            ++cnt[s[k]];
            total[s[k]] += k;
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值