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;
}
};

本文介绍了如何找出存在于多个整数数组中的交集元素,以及解决股票价格波动问题。针对数组交集,提出了使用哈希集合和哈希映射来统计每个元素在数组中出现的次数,从而找到至少在两个数组中出现的元素。对于股票价格波动问题,使用有序映射和哈希表记录价格和时间戳,确保在O(1)时间内获取当前、最大和最小价格。这两个问题都涉及到了数据结构的有效利用和高效算法设计。
1200

被折叠的 条评论
为什么被折叠?



