《黑神话:悟空》
距离《黑神话:悟空》上线(8 月 20 日)上线已过去半个月,从刚开始全网热议,连官方都下场点评,到现在的逐渐回归平静。
不是游戏圈或是对数据不敏感的网友,可能会落入《黑神话:悟空》已经开始失势的"错觉"中。
但实际上,《黑神话:悟空》还在持续不断的创造新历史。
据最新的机构统计数据显示,《黑神话:悟空》上市两周,销量已突破 1800 万份,营销收入高达 8.67 亿美元。
要知道,在上市前两周,网友还在讨论《黑神话:悟空》到底能不能卖出 300 万份,能不能保本;上市前一周还在讨论,能不能摸到 500 万份的门槛;上市前三天还在遐想,冲击完第一波销售额之后,慢慢卖,利用长尾效应该能达到 1000 万份。
现在一个月不到,已经 1800 万份了,比此前最乐观的预期还再要高几个档次。
之前我们提到过 《黑神话:悟空》这家公司的薪资水平 ,无论是深圳还是杭州,都属于没有竞争力的一档,但这一波 1800 万份销量,再加上后续的 DLC 以及 IP 续集开发,保底赚它 100 亿,这已经不是年终奖几十个月的问题,而是整个游戏工作室集体财务自由。
对的,我说的是整个游戏工作室。
游戏科学有 30%+ 的股份在老板手上,另外还有 30%+ 的股份为员工集体持有。
有时候我们会调侃一些项目,三年不开张,开张吃三年,《黑神话:悟空》这一波是四年不开张,开张上百亿(25 倍的回报率)。
...
回归主题。
周五了,来一道不太困难算法题。
题目描述
平台:LeetCode
题号:992
给定一个正整数数组 A
,如果 A
的某个子数组中不同整数的个数恰好为 K
,则称 A
的这个连续、不一定不同的子数组为好子数组。
例如, 中有 3 个不同的整数:1,2,以及 3。
返回 A
中好子数组的数目。
示例 1:
输入:A = [1,2,1,2,3], K = 2
输出:7
解释:恰好由 2 个不同整数组成的子数组:[1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2]
示例 2:
输入:A = [1,2,1,3,4], K = 3
输出:3
解释:恰好由 3 个不同整数组成的子数组:[1,2,1,3], [2,1,3], [1,3,4]
提示:
滑动窗口
对原数组每个 而言:
-
找到其左边「最远」满足出现 个不同字符的下标,记为 ,这时候形成的区间为 -
找到其左边「最远」满足出现 个不同字符的下标,记为 ,这时候形成的区间为 -
「那么对于 其实就是代表以 为右边界(必须包含 ),不同字符数量「恰好」为 的子数组数量」
我们使用 lower
数组存起每个位置的 p
;使用 upper
数组存起每个位置的 j
。
累积每个位置的 就是答案。
计算 lower
数组 和 upper
数组的过程可以使用双指针。
Java 代码:
class Solution {
public int subarraysWithKDistinct(int[] nums, int k) {
int n = nums.length, ans = 0;
int[] lower = new int[n], upper = new int[n];
find(nums, lower, k);
find(nums, upper, k - 1);
for (int i = 0; i < n; i++) ans += upper[i] - lower[i];
return ans;
}
void find(int[] nums, int[] arr, int k) {
int n = nums.length;
int[] cnt = new int[20010];
for (int i = 0, j = 0, sum = 0; j < n; j++) {
if (++cnt[nums[j]] == 1) sum++;
while (sum > k) {
if (--cnt[nums[i++]] == 0) sum--;
}
if (sum == k) arr[j] = i;
}
}
}
C++ 代码:
class Solution {
public:
int subarraysWithKDistinct(vector<int>& nums, int k) {
int n = nums.size(), ans = 0;
vector<int> lower(n, 0), upper(n, 0);
find(nums, lower, k);
find(nums, upper, k - 1);
for (int i = 0; i < n; i++) ans += upper[i] - lower[i];
return ans;
}
void find(vector<int>& nums, vector<int>& arr, int k) {
int n = nums.size();
unordered_map<int, int> cnt;
int i = 0, j = 0, sum = 0;
for (j = 0; j < n; j++) {
if (++cnt[nums[j]] == 1) sum++;
while (sum > k) {
if (--cnt[nums[i++]] == 0) sum--;
}
if (sum == k) arr[j] = i;
}
}
};
Python 代码:
class Solution:
def subarraysWithKDistinct(self, nums: List[int], k: int) -> int:
n, ans = len(nums), 0
lower, upper = [0] * n, [0] * n
self.find(nums, lower, k)
self.find(nums, upper, k - 1)
return sum(upper[i] - lower[i] for i in range(n))
def find(self, nums, arr, k):
n = len(nums)
cnt = defaultdict(int)
i, j, sumv = 0, 0, 0
while j < n:
if cnt[nums[j]] == 0:
sumv += 1
cnt[nums[j]] += 1
while sumv > k:
cnt[nums[i]] -= 1
if cnt[nums[i]] == 0:
sumv -= 1
i += 1
if sumv == k:
arr[j] = i
j += 1
-
时间复杂度:对数组进行常数次扫描。复杂度为 。 -
空间复杂度:
最后
巨划算的 LeetCode 会员优惠通道目前仍可用 ~
使用福利优惠通道 leetcode.cn/premium/?promoChannel=acoier,年度会员 有效期额外增加两个月,季度会员 有效期额外增加两周,更有超大额专属 🧧 和实物 🎁 福利每月发放。
我是宫水三叶,每天都会分享算法知识,并和大家聊聊近期的所见所闻。
欢迎关注,明天见。
更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地 🎉🎉