由于 10^9<2^{30,我们可以直接预计算所有 s 中长度不超过 30 的数及其对应的 left 和 right,记到一个哈希表中,然后 O(1) 地回答询问。
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defsubstringXorQueries(self, s: str, queries: List[List[int]]) -> List[List[int]]: n, m = len(s), {} if (i := s.find('0')) >= 0: m[0] = (i, i) # 这样下面就可以直接跳过 '0' 了,效率更高 for l, c inenumerate(s): if c == '0': continue x = 0 for r inrange(l, min(l + 30, n)): x = (x << 1) | (ord(s[r]) & 1) if x notin m: m[x] = (l, r) NOT_FOUND = (-1, -1) return [m.get(x ^ y, NOT_FOUND) for x, y in queries]
classSolution { public: vector<vector<int>> substringXorQueries(string s, vector<vector<int>> &queries) { unordered_map<int, pair<int, int>> m; if (auto i = s.find('0'); i != string::npos) m[0] = {i, i}; // 这样下面就可以直接跳过 '0' 了,效率更高 for (int l = 0, n = s.length(); l < n; ++l) { if (s[l] == '0') continue; for (int r = l, x = 0; r < min(l + 30, n); ++r) { x = x << 1 | (s[r] & 1); if (!m.count(x)) m[x] = {l, r}; } }
vector<vector<int>> ans; for (auto &q : queries) { auto it = m.find(q[0] ^ q[1]); if (it == m.end()) ans.push_back({-1, -1}); else ans.push_back({it->second.first, it->second.second}); } return ans; } };
funcsubstringXorQueries(s string, queries [][]int) [][]int { type pair struct{ l, r int } m := map[int]pair{} if i := strings.IndexByte(s, '0'); i >= 0 { m[0] = pair{i, i} // 这样下面就可以直接跳过 '0' 了,效率更高 } for l, c := range s { if c == '0' { continue } for r, x := l, 0; r < l+30 && r < len(s); r++ { x = x<<1 | int(s[r]&1) if _, ok := m[x]; !ok { m[x] = pair{l, r} } } }
ans := make([][]int, len(queries)) notFound := []int{-1, -1} // 避免重复创建 for i, q := range queries { p, ok := m[q[0]^q[1]] if !ok { ans[i] = notFound } else { ans[i] = []int{p.l, p.r} } } return ans }
复杂度分析
时间复杂度:O(n\log U + q),其中 n 为 s 的长度,U=max(\textit{queries}),q 为 queries 的长度。