5894. 至少在两个数组中出现的值
给你三个整数数组 nums1、nums2 和 nums3 ,请你构造并返回一个 不同 数组,且由 至少 在 两个 数组中出现的所有值组成。数组中的元素可以按 任意 顺序排列。
示例 1:
输入:nums1 = [1,1,3,2], nums2 = [2,3], nums3 = [3]
输出:[3,2]
解释:至少在两个数组中出现的所有值为:
- 3 ,在全部三个数组中都出现过。
- 2 ,在数组 nums1 和 nums2 中出现过。
示例 2:
输入:nums1 = [3,1], nums2 = [2,3], nums3 = [1,2]
输出:[2,3,1]
解释:至少在两个数组中出现的所有值为:
- 2 ,在数组 nums2 和 nums3 中出现过。
- 3 ,在数组 nums1 和 nums2 中出现过。
- 1 ,在数组 nums1 和 nums3 中出现过。
示例 3:
输入:nums1 = [1,2,2], nums2 = [4,3,3], nums3 = [5]
输出:[]
解释:不存在至少在两个数组中出现的值。
提示:
1 <= nums1.length, nums2.length, nums3.length <= 100
1 <= nums1[i], nums2[j], nums3[k] <= 100
求解
题目很简洁,只需要找出在三个数组中至少在两个数组中出现过的数字,笔者用了一种比较笨的方式:
首先通过 unordered_set 记录好数组中的所有元素,然后将集合中的元素再往 unordered_map 记录,其中 key表示该数,value表示在三个数组中出现的情况(出现一次记为1,出现两次记为2…),对三个数组都进行前述操作,最后可以判断 哈希表中 的元素value是否大于1判断该元素是否符合题中条件。
class Solution {
public:
vector<int> twoOutOfThree(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3) {
unordered_map<int, int> hash_map;//记录该数在三个数组中出现的次数
unordered_set<int> quchong;//使用哈希集合去重再统计
for (auto& num : nums1) {
if(quchong.count(num) == 0)
quchong.insert(num);
}
for (auto it = quchong.begin(); it != quchong.end(); ++it) {
++hash_map[*it];
}
quchong.clear();
for (auto& num : nums2) {
if (quchong.count(num) == 0)
quchong.insert(num);
}
for (auto it = quchong.begin(); it != quchong.end(); ++it) {
++hash_map[*it];
}
quchong.clear();
for (auto& num : nums3) {
if (quchong.count(num) == 0)
quchong.insert(num);
}
for (auto it = quchong.begin(); it != quchong.end(); ++it) {
++hash_map[*it];
}
vector<int> ans;//遍历哈希表,将大于1的值装入答案数组中
for (auto it = hash_map.begin(); it != hash_map.end(); ++it) {
if (it->second > 1) {
ans.push_back(it->first);
}
}
return ans;
}
};
- 时间复杂度: O(N)
- 空间复杂度: O(N)
5895. 获取单值网格的最小操作数
给你一个大小为 m x n 的二维整数网格 grid 和一个整数 x 。每一次操作,你可以对 grid 中的任一元素 加 x 或 减 x 。
单值网格 是全部元素都相等的网格。
返回使网格化为单值网格所需的 最小 操作数。如果不能,返回 -1 。
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 10^5
1 <= m * n <= 10^5
1 <= x, grid[i][j] <= 10^4
求解
这道题没写出来,贴上大佬@吴自华的题解吧 0.0
(题解地址:Leetcode 第262场周赛题解)
class Solution {
public:
int minOperations(vector<vector<int>>& grid, int x) {
int n = grid.size(), m = grid[0].size(), mod = grid[0][0] % x;
vector<int> v;
for (auto &row : grid)
for (int cell : row) {
if (cell % x != mod)
return -1;
v.emplace_back(cell / x);
}
int mid = n * m / 2;
nth_element(v.begin(), v.begin() + mid, v.end());
int ans = 0;
for (int vi : v)
ans += abs(vi - v[mid]);
return ans;
}
};
作者:吴自华
链接:https://leetcode-cn.com/circle/discuss/2ELXyY/view/DxDKIC/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
5896. 股票价格波动
示例 1:
输入:
["StockPrice", "update", "update", "current", "maximum", "update", "maximum", "update", "minimum"]
[[], [1, 10], [2, 5], [], [], [1, 3], [], [4, 2], []]
输出:
[null, null, null, 5, 10, null, 5, null, 2]
解释:
StockPrice stockPrice = new StockPrice();
stockPrice.update(1, 10); // 时间戳为 [1] ,对应的股票价格为 [10] 。
stockPrice.update(2, 5); // 时间戳为 [1,2] ,对应的股票价格为 [10,5] 。
stockPrice.current(); // 返回 5 ,最新时间戳为 2 ,对应价格为 5 。
stockPrice.maximum(); // 返回 10 ,最高价格的时间戳为 1 ,价格为 10 。
stockPrice.update(1, 3); // 之前时间戳为 1 的价格错误,价格更新为 3 。
// 时间戳为 [1,2] ,对应股票价格为 [3,5] 。
stockPrice.maximum(); // 返回 5 ,更正后最高价格为 5 。
stockPrice.update(4, 2); // 时间戳为 [1,2,4] ,对应价格为 [3,5,2] 。
stockPrice.minimum(); // 返回 2 ,最低价格时间戳为 4 ,价格为 2 。
提示:
1 <= timestamp, price <= 10^9
update,current,maximum 和 minimum 总 调用次数不超过 105 。
current,maximum 和 minimum 被调用时,update 操作 至少 已经被调用过 一次 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/stock-price-fluctuation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
求解
由于笔者对数据流类型的题不怎么拿手,刚开始做的时候遇到了一些麻烦:最初想维护一个降序链表,链表节点记录时间戳以及股票价格(按照价格排序),这样就可以在O(1) 时间下获得股票最高或最低价格,选用链表是因为考虑到有大量的更正操作,即需要查找之前的信息并更新,如果使用数组,那么想要保证有序对元素修改,势必会造成大量元素拷贝,时间上消耗过大。
返回最新价格的就可以简单的通过使用哈希表实现,用一个变量记录最新的时间戳 timestamp 是多少,即可在O(1)时间复杂度下查找到对应的股票价格。
但是算法还是需要改进的(尝试提交之后超时了。。。)
后来换了一种思路:
使用有序列表map<int,int>:key表示股票的价格,value表示该价格出现的次数。
再使用哈希表 unordered_map<int,int> 记录各个时间戳对应的股票价格。
有了这个思路,代码变得就很简单了:
class StockPrice {
public:
struct cmp {
bool operator()(const int& a, const int& b)const {
return a > b;
}
};
int maxStamp = INT_MIN;
map<int, int, cmp> prices;//记录出现过的价格 以及 数量
unordered_map<int, int> time_price;//实现 时间戳 到 price 的转换
StockPrice() {
}
void update(int timestamp, int price) {
maxStamp = max(maxStamp, timestamp);
if (time_price.count(timestamp) == 1) {//之前有过
int pre = time_price[timestamp];
if (prices[pre] == 1) {
prices.erase(pre);
}
else {
--prices[pre];
}
}
++prices[price];
time_price[timestamp] = price;
}
int current() {
return time_price[maxStamp];
}
int maximum() {
return prices.begin()->first;
}
int minimum() {
return prices.rbegin()->first;
}
};