auto indices = array<char*, 12>{}; // find all the letters in S, associate them with numbers auto letter_num = 0u; for(auto& c : S) { if(isalpha(c)) { indices[letter_num++] = &c; } }
// compute the maximum for an interger that has 'letter_num' bits constauto max = 1 << letter_num;
auto res = vector<string>{}; for(auto i = 0u; i < max; ++i) { auto bs = bitset<12>{i}; for(auto j = 0u; j < letter_num; ++j) { // uppercase if(bs[j]) { auto c = toupper(*indices[j]); *indices[j] = c; } // lowercase else { auto c = tolower(*indices[j]); *indices[j] = c; } }
classSolution { public: intfindMaximumXOR(vector<int>& nums){ // prefix-mask auto pmask = bitset<32>{}; auto res = bitset<32>{}; for(auto i = 31; i >= 0; --i) { pmask.set(i); auto pmap = unordered_set<uint32_t>{}; // put all prefixes of nums into a hashset for(uint32_t n : nums) { pmap.insert(pmask.to_ulong() & n); }
//assume that the i bit is 1 auto pres = res; pres.set(i);
//check if pres xor nums is in the hashset for(uint32_t n : nums) { if(pmap.find( (pmask.to_ulong() & n) ^ // prefix pres.to_ulong()) // assumption != pmap.end()) { res = pres; break; } } }
classSolution { public: intfindMaximumXOR(vector<int>& nums){ // prefix-mask auto pmask = 0; auto res = 0; for(auto i = 31; i >= 0; --i) { pmask |= (1 << i); auto pmap = unordered_set<uint32_t>{}; // put all prefixes of nums into a hashset for(uint32_t n : nums) { pmap.insert(pmask & n); }
//assume that the i bit is 1 auto pres = res; pres |= (1 << i);
//check if pres xor nums is in the hashset for(uint32_t n : nums) { if(pmap.find((pmask & n) ^ pres) != pmap.end()) { res = pres; break; } } }
template<typename It> autorange_num(It first, It last) -> size_t { auto res = 0ul; for(;first != last; ++first) { for(auto e = first + 1; e < last; ++e) { res += *e - *first - 1; } } return res; }
classSolution { public: intcountTriplets(vector<int>& arr){ // make an xor partial sum array auto xor_sum = vector<int>{}; // to make the computation of length for all subarrays like (0, m], insert a 0 to the beginning. xor_sum.push_back(0); partial_sum(arr.begin(), arr.end(), back_inserter(xor_sum), [](auto lhs, auto rhs) { return lhs ^ rhs; });
// associate each xor partial sum result with its position auto counter = unordered_map<int, vector<size_t>>{}; for(auto i = 0u; i < arr.size() + 1; ++i) { counter[xor_sum[i]].push_back(i); }
// compute the sum of lengths of all subarrays. auto res = 0ul; for(auto& pair : counter) { if(pair.second.size() > 1) { sort(pair.second.begin(), pair.second.end()); res += range_num(pair.second.begin(), pair.second.end()); } }
classSolution { public: intmissingNumber(vector<int>& nums){ int res = 0; int i = 0; for(; i < nums.size(); ++i) res = res ^ i ^ nums[i]; return res ^ i; } };
classSolution { public: intsingleNumber(vector<int>& nums){ int result = nums[0]; for(size_t i = 1; i < nums.size(); ++i){ result ^= nums[i]; } return result; } };
3xN + 1
再复杂一点的就是LC137 Single Number II,每个数字都出现了3次。这个时候就不能用XOR了,我们需要设计个vector来统计所有数字中每一位1出现的个数。因为所有其他数字都出现了三次,那么在这一位上,所有其他数字1出现的个数也是3的倍数。这样我们就可以对每一位都mod 3,如果mod的结果是1,那么那个Single Number那一位就是1,否则就是0。之后使用这个数组还原single number即可。
for_each(bits.begin(), bits.end(), [](auto& n) { n %= 3; });
auto res = 0;
for(auto i = 0u; i < bits.size(); ++i) { if(bits[i]) { res |= (1u << i); } }
return res; } };
2xN + 1 + 1
最复杂的就是LC260 Single Number III,这个题目里面有两个出现一次的,其他出现两次。我们按照最简单的[LC136 Single Number]的思路,把数组里面的数字先都XOR一下,这样我们就得到了两个出现一次的数字的XOR的结果。现在的问题是:怎么利用【XOR的结果】 和 【数组】 来还原这两个Single Number呢? 剑指Offer 56里提供的方案是,用xor结果里第一个为1的位作为标志(bitMask),将数组分为两部分。 出现了两次的数字,因为其在(bitMask)这一位上必然是相同,也就会被分到同一组中。而不同的两个数字,在(bitMask)上必然是不同的,也就被分开了。之后在两组上再做xor,就得到那不同的那两个数字了。
n和m二进制位数一样多 不断同时右移n和m直到n和m相等,变化只会发生在这两个相等的后面,因此将后面补零即可 m = 1000, n = 1100 —> 相等的是最高位的1,过程中所有数:1000->1001->1010->1011->1100
code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution { public: intrangeBitwiseAnd(int m, int n){ int shift = 0; // this contains two situations // m has the same num of digits as n --> m and n will be 0 // m has different same num of digits with n --> move to the lowest common digits while(m != n) { m >>= 1; n >>= 1; ++shift; } return m << shift; } };