A 找出强数对的最大异或值 I
模拟
cpp
class Solution {
public:
int maximumStrongPairXor(vector<int> &nums) {
int n = nums.size();
int res = 0;
for (auto x: nums)
for (auto y: nums)
if (abs(x - y) <= min(x, y))
res = max(res, x ^ y);
return res;
}
};
B 高访问员工
哈希+排序:用哈希表记录各个员工所有的访问时间,并对访问时间排序,然后遍历排序后的相邻三元组判断
cpp
class Solution {
public:
vector<string> findHighAccessEmployees(vector<vector<string>> &access_times) {
unordered_map<string, vector<int>> li;
for (auto &it: access_times)//时间转化为总秒数
li[it[0]].push_back(getint(it[1][0]) * 600 + getint(it[1][1]) * 60 + getint(it[1][2]) * 10 + getint(it[1][3]));
vector<string> res;
for (auto &[k, v]: li) {
sort(v.begin(), v.end());
for (int i = 2; i < v.size(); i++)
if (v[i] - v[i - 2] < 60) {
res.push_back(k);
break;
}
}
return res;
}
inline int getint(char ch) {
return ch - '0';
}
};
C 最大化数组末位元素的最少操作次数
模拟:分两种情况:1)不交换 n u m s 1 [ n − 1 ] nums1[n - 1] nums1[n−1] 和 n u m s 2 [ n − 1 ] nums2[n - 1] nums2[n−1] ;2)交换 n u m s 1 [ n − 1 ] nums1[n - 1] nums1[n−1] 和 n u m s 2 [ n − 1 ] nums2[n - 1] nums2[n−1]。每种情况下遍历 i ∈ [ 0 , n ) i\in [0,n) i∈[0,n) ,若 n u m s 1 [ i ] > n u m s 1 [ n − 1 ] nums1[i] > nums1[n-1] nums1[i]>nums1[n−1] 或 n u m s 2 [ i ] > n u m s 2 [ n − 1 ] nums2[i] > nums2[n-1] nums2[i]>nums2[n−1],则交换 n u m s 1 [ i ] nums1[i] nums1[i] 和 n u m s 2 [ i ] nums2[i] nums2[i],若交换后仍有 n u m s 1 [ i ] > n u m s 1 [ n − 1 ] nums1[i] > nums1[n-1] nums1[i]>nums1[n−1] 或 n u m s 2 [ i ] > n u m s 2 [ n − 1 ] nums2[i] > nums2[n-1] nums2[i]>nums2[n−1],则当前情况无解。
cpp
class Solution {
public:
int inf = 1e7;
int get(vector<int> nums1, vector<int> nums2) {
int res = 0;
for (int i = 0; i < nums1.size(); i++)
if (nums1[i] > nums1.back() || nums2[i] > nums2.back()) {
swap(nums1[i], nums2[i]);
res++;
if (nums1[i] > nums1.back() || nums2[i] > nums2.back())
return inf;
}
return res;
}
int minOperations(vector<int> &nums1, vector<int> &nums2) {
int res = get(nums1, nums2);//不交换 nums1[n - 1] 和 nums2[n - 1]的情况
swap(nums1.back(), nums2.back());
res = min(res, 1 + get(nums1, nums2));//交换 nums1[n - 1] 和 nums2[n - 1]的情况
return res == inf ? -1 : res;
}
};
D 找出强数对的最大异或值 II
滑动窗口 + 字典树:不妨设 x ≤ y x\le y x≤y ,则满足 2 × x ≤ y 2\times x\le y 2×x≤y 则 x x x 和 y y y 可构成强数对,对数组排序后枚举 y y y,同时
用滑动窗口维护满足条件的 x x x ,过程中用字典树维护当前满足条件的 x x x 的集合,同时通过字典树查询与 y y y 构成的强数对的最大异或值
cpp
class Trie {//字典树
public:
vector<Trie *> next = vector<Trie *>(2, nullptr);
int cnt = 0;//子树中的数的数目
void insert(int v) {//往字典树中插入v
Trie *cur = this;
for (int i = 19; i >= 0; i--) {
cur->cnt++;//更新计数
int t = v >> i & 1;
if (!cur->next[t])
cur->next[t] = new Trie();
cur = cur->next[t];
}
cur->cnt++;//更新计数
}
void del(int v) {//删除字典树中的v
Trie *cur = this;
for (int i = 19; i >= 0; i--) {
cur->cnt--;//更新计数
int t = v >> i & 1;
cur = cur->next[t];
}
cur->cnt--;//更新计数
}
int query(int y) {//查询与y构成的强数对的最大异或值
int res = 0;
Trie *cur = this;
for (int i = 19; i >= 0; i--) {
int t = y >> i & 1;
if (!cur->next[t ^ 1] || cur->next[t ^ 1]->cnt == 0)
cur = cur->next[t];
else {
cur = cur->next[t ^ 1];
res |= 1 << i;
}
}
return res;
}
};
class Solution {
public:
int maximumStrongPairXor(vector<int> &nums) {
int n = nums.size();
sort(nums.begin(), nums.end());
Trie trie;
int res = 0;
for (int iy = 0, ix = 0; iy < n; iy++) {//枚举y (nums[iy])
trie.insert(nums[iy]);//插入y
while (2 * nums[ix] < nums[iy])//更新滑动窗口左端点
trie.del(nums[ix++]);//删除无法与y构成强数对的x
res = max(res, trie.query(nums[iy]));//查询与y构成的强数对的最大异或值
}
return res;
}
};