Q1 找出强数对的最大异或值I
-
解题思路:
- 二重循环枚举x,y
- 对于满足条件的x,y,计算其异或值,并更新答案
-
解题代码:
class Solution {
public:
int maximumStrongPairXor(vector<int>& nums) {
int n = nums.size();
int ans = 0;
for(int i = 0; i < n; i++)
{
for(int j = i; j < n; j++)
{
if(abs(nums[i] - nums[j]) <= min(nums[i], nums[j]))
ans = max(ans, nums[i] ^ nums[j]);
}
}
return ans;
}
};
Q2 高访问员工
-
解题思路:
- 将所有访问时间转换成秒
- 按照访问时间从小到大进行排序
- 对每个员工统计一个小时内的访问次数,可以用队列进行统计,队列内存储在一个小时内的访问时间,如果队列中的元素个数大于等于3,将该员工加到答案中
-
解题代码:
class Solution {
public:
int string2Num(string time)
{
int num = 0;
num = ((time[0] - '0') * 10 + (time[1] - '0')) * 60 + (time[2] - '0') * 10 + time[3] - '0';
return num;
}
vector<string> findHighAccessEmployees(vector<vector<string>>& access_times) {
vector<pair<string, int>> times;
for(auto &access_time : access_times)
times.push_back({access_time[0], string2Num(access_time[1])});
sort(times.begin(), times.end(), [](const pair<string, int>& a, const pair<string, int>& b)
{
return a.second < b.second;
});
unordered_map<string, queue<int>> um;
unordered_set<string> us;
for(auto &[name, time] : times)
{
while(!um[name].empty() && um[name].front() + 60 <= time)
um[name].pop();
um[name].push(time);
if(um[name].size() >= 3)
us.insert(name);
}
vector<string> ans(us.begin(), us.end());
return ans;
}
};
- 更高效的实现,先按照名字去分组,然后组内排序处理
class Solution {
public:
vector<string> findHighAccessEmployees(vector<vector<string>>& access_times) {
unordered_map<string, vector<int>> um;
for(auto &access_time : access_times)
{
int time = stoi(access_time[1].substr(0, 2)) * 60 + stoi(access_time[1].substr(2, 2));
um[access_time[0]].push_back(time);
}
vector<string> ans;
for(auto &[name, time] : um)
{
sort(time.begin(), time.end());
int len = time.size();
for(int i = 2; i < len; i++)
{
if(time[i] - time[i-2] < 60)
{
ans.push_back(name);
break;
}
}
}
return ans;
}
};
Q3 最大化数组末位元素的最小操作次数
-
解题思路:
-
直接分两种情况来讨论:
- 不交换末位元素
- 交换末位元素
-
分别检查对于前面的元素最少需要交换多少次(能不换就不换)
-
-
解题代码:
class Solution {
public:
int minOperations(vector<int>& nums1, vector<int>& nums2) {
int ans = INT_MAX;
int n = nums1.size();
//不交换
int cnt = 0;
for(int i = 0; i < n-1; i++)
{
if(nums1[i] <= nums1.back() && nums2[i] <= nums2.back())
continue;
if(nums1[i] <= nums2.back() && nums2[i] <= nums1.back())
{
cnt += 1;
continue;
}
cnt = INT_MAX;
break;
}
ans = min(ans, cnt);
//交换
cnt = 1;
for(int i = 0; i < n-1; i++)
{
if(nums1[i] <= nums2.back() && nums2[i] <= nums1.back())
continue;
if(nums1[i] <= nums1.back() && nums2[i] <= nums2.back())
{
cnt += 1;
continue;
}
cnt = INT_MAX;
break;
}
ans = min(ans, cnt);
if(ans == INT_MAX)
return -1;
return ans;
}
};
- 应该提一个函数出来的
class Solution {
public:
int minOperations(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size();
auto func = [&](int last1, int last2) -> int
{
int cnt = 0;
for(int i = 0; i < n-1; i++)
{
if(nums1[i] <= last1 && nums2[i] <= last2)
continue;
if(nums1[i] <= last2 && nums2[i] <= last1)
{
cnt += 1;
continue;
}
return n+1;
}
return cnt;
};
int ans = min(func(nums1.back(), nums2.back()), func(nums2.back(), nums1.back()) + 1);
if(ans > n)
return -1;
return ans;
}
};
Q4 找出强数对的最大异或值II
-
解题思路:
- 先将数组进行排序
- 当y 大于 x时,条件可以化简为 y - x <= x => y <= 2x
- 枚举y,在满足 2x >= y 的范围内找最大的异或值
- 使用0-1字典树
-
解题代码:
class Trie{
public:
Trie():child(2, nullptr), cnt(0){}
void insert(int num)
{
Trie *cur = this;
for(int i = 20; i >= 0; i--)
{
int bit = num >> i & 1;
if(!cur->child[bit])
cur->child[bit] = new Trie();
cur = cur->child[bit];
cur->cnt += 1;
}
}
void del(int num)
{
Trie *cur = this;
for(int i = 20; i >= 0; i--)
{
int bit = num >> i & 1;
cur = cur->child[bit];
cur->cnt -= 1;
}
}
int query(int num)
{
Trie *cur = this;
int ans = 0;
for(int i = 20; i >= 0; i--)
{
int bit = num >> i & 1;
if(cur->child[1-bit] && cur->child[1-bit]->cnt != 0)
{
cur = cur->child[1 - bit];
ans |= 1 << i;
}
else
cur = cur->child[bit];
}
return ans;
}
private:
vector<Trie*> child;
int cnt;
};
class Solution {
public:
int maximumStrongPairXor(vector<int>& nums) {
int ans = 0;
sort(nums.begin(), nums.end());
int l = 0, r = 0;
int n = nums.size();
Trie *root = new Trie();
while(r < n)
{
while(nums[l] * 2 < nums[r])
{
root->del(nums[l]);
l += 1;
}
root->insert(nums[r]);
ans = max(ans, root->query(nums[r]));
r += 1;
}
return ans;
}
};
- 用哈希表来做
class Solution {
public:
int maximumStrongPairXor(vector<int>& nums) {
sort(nums.begin(), nums.end());
int high_bit = 31 - __builtin_clz(nums.back());//最高位是哪一位
int ans = 0, mask = 0;
unordered_map<int, int> mp;
for(int i = high_bit; i >= 0; i--)
{
mp.clear();
mask |= 1 << i;
int new_ans = ans | (1 << i);
for(auto y : nums)
{
int mask_y = y & mask;
auto it = mp.find(new_ans ^ mask_y);
if(it != mp.end() && it->second * 2 >= y)
{
ans = new_ans;
break;
}
mp[mask_y] = y;
}
}
return ans;
}
};