给出一个大小为n的数组a和整数t,定义区间[l,r](0<=l<r<=n-1),若存在下标i,j(l<=i<j<=r)属于区间[l,r],且a[i]异或a[j]=t,那么称[l,r]是非奇特区间,如不存在,则[l,r]是奇特区间,求a数组里的奇特区间个数。
[2,4,8],6
1
因为2异或4为6,等于t,所以只有区间[1,2]是奇特区间,对应的数组是[4,8],数组不能为[2,4],数组也不能为[2,4,8],因为里面包含了2和4
[2,3,4],6
2
因为2异或4为6,等于t,所以区间[0,1],[1,2]是奇特区间,对应的数组分别为[2,3],[3,4]
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param a int整型一维数组 * @param t int整型 * @return long长整型 */ public long section (int[] a, int t) { // write code here int n = a.length; HashMap<Integer, Integer> counter = new HashMap<>(); int left = 0, right = 0; long count = 0; while(right < n){ counter.put(a[right], counter.getOrDefault(a[right], 0) + 1); while(counter.containsKey(a[right] ^ t)){ // 收缩左边界 if(counter.get(a[left]) == 1){ counter.remove(a[left]); }else{ counter.put(a[left], counter.get(a[left]) - 1); // 排除一个能与a[right]异或得到t的值 } left++; } count += right - left; // 扩张右边界 right++; } return count; } }
func section( a []int , t int ) int64 { // 存在a[i]^a[j] == t 就不是奇特区间 // 用map 存储出现的数,并且遍历到j时判断a[j]^t是否存在 // a[i] == a[j]^t 就不是奇特区间 m := make(map[int]int, 0) l, r := 0, 0 ans := 0 for r < len(a) { m[a[r]] = r for { if idx, ok := m[a[r]^t]; !ok || idx < l { break } else { l = idx+1 } } // fmt.Println(l, r) ans += r-l r ++ } return int64(ans) }
class Solution { public: long long section(vector<int>& a, int t) { // write code here unordered_map<int, int> un; long long ans = 0; int l = 0, r = 0; while (r < a.size()) { if (un.count(a[r] ^ t) > 0) { l = max(l, un.at(a[r] ^ t) + 1); } ans += r - l; un[a[r]] = r; r++; } return ans; } };
public long section (int[] a, int t) { // write code here int l = 0, r = 1; long res = 0; Map<Integer,Integer> map = new HashMap<>(); map.put(a[l],l); while(r < a.length) { int now = a[r]; if(map.containsKey(now^t)) { l = Math.max(map.get(now^t) + 1, l); } res += r - l; map.put(now,r); r++; } return res; }map记录出现数字的下标,每次冲突,左边界直接跳到冲突数字的下一个
这个问题要求找出所有的“奇特区间”,这些区间定义为在一个给定数组 a
中,不存在两个元素 a[i]
和 a[j]
(其中 i < j
)使得它们的异或结果等于给定的整数 t
。
解决这个问题的一个有效方法是使用滑动窗口技术。具体步骤如下:
初始化两个指针 left
和 right
,它们都从数组的起始位置开始。这两个指针将定义一个窗口,窗口内的元素是当前考虑的子数组。
遍历数组,逐渐扩大窗口的右边界。对于每个新的 right
位置,我们检查在这个位置之前的所有元素是否存在某个元素,与 a[right]
的异或结果等于 t
。如果存在,说明当前窗口不是奇特区间,我们需要收缩左边界直到排除这种情况。
如果在当前窗口内,没有找到与 a[right]
异或等于 t
的元素,那么从 left
到 right
的所有子区间都是奇特区间。
使用一个哈希表来记录窗口内元素的出现次数,以便快速检查是否存在与 a[right]
异或等于 t
的元素。
在窗口右移的过程中,累加奇特区间的数量。
class Solution: def section(self, a, t): n = len(a) # 获取数组的长度 left = 0 # 初始化左指针 right = 0 # 初始化右指针 count = 0 # 用于计数奇特区间的数量 counter = {} # 用于存储数组中各元素的出现次数 while right < n: # 遍历数组 # 将当前右指针所指元素的计数加1 counter[a[right]] = counter.get(a[right], 0) + 1 # 如果存在使得异或等于t的元素,开始收缩左边界 while counter.get(a[right] ^ t, 0) > 0: # 减少左指针所指元素的计数 counter[a[left]] -= 1 # 如果左指针所指元素计数为0,则从counter中移除该元素 if counter[a[left]] == 0: del counter[a[left]] # 左指针向右移动 left += 1 # 计算并累加奇特区间的数量 count += right - left # 右指针向右移动 right += 1 return count # 返回奇特区间的总数 # 示例使用 sol = Solution() print(sol.section([2, 4, 8], 6)) # 输出: 1 print(sol.section([2, 3, 4], 6)) # 输出: 2
from collections import defaultdict class Solution: def section(self , a , t ): lenth = len(a) if lenth < 2: return 0 cache = defaultdict(int) l, r = 0, 1 cache[a[l]] += 1 result = 0 while r < lenth: while cache[a[r] ^ t] > 0: cache[a[l]] -= 1 l += 1 cache[a[r]] += 1 result += r - l r += 1 return result
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param a int整型vector * @param t int整型 * @return long长整型 */ typedef long long LL; long long section(vector<int>& a, int t) { // write code here LL res = 0; int n = a.size(), L = 0; unordered_map<int, int> cnt; for(int i = 0; i < a.size(); i ++) { if(cnt.count(a[i])) { L = max(L, cnt[a[i]] + 1); } res = res + 0ll + i - L; cnt[a[i] ^ t] = i; } return res; } };
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param a int整型vector * @param t int整型 * @return long长整型 */ long long section(vector<int>& a, int t) { // write code here unordered_map<int,int> mp; long long res=0; int l=0,r=0; while(r<a.size()){ mp[a[r]]++; while(mp.count(a[r]^t) && mp[a[r]^t]>0){ mp[a[l]]--; l++; } res+=(r-l); r++; } return res; } };
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param a int整型vector * @param t int整型 * @return long长整型 */ long long section(vector<int>& a, int t) { // write code here using ll = long long; ll res = 0; int n = (int)a.size(); unordered_map<int, int> cnt; if (n < 2) return 0; cnt[a[0]]++; int l = 0, r = 1; while (r < n) { int c = t^a[r]; while (cnt.count(c) > 0) { res += max(0, r-l-1); if (--cnt[a[l]] == 0) cnt.erase(a[l]); l++; } cnt[a[r++]]++; } for (int i = l; i < n-1; ++i) res += max(0, r-i-1); return res; } };