力扣第 262 场周赛总结

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

在这里插入图片描述

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nepu_bin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值