大家好,我是吴师兄,关注我,每周更新大厂最新笔试题解析。
小美想要买糖果店的一根长长的糖果,糖果店顾客可以从中选取一个位置然后老板会在那切断,糖果前端到那个切断位置的糖果就会出售给这位顾客。这个糖果其实不同段有着不同的口味,小美希望她选出来的糖果中各个段有着不同的口味,在这基础上希望能选出尽可能长的糖果。小美想知道她能买到最长多长的糖果,请你帮帮她。
第一行1
个整数n
,表示糖果的长度。
第二行n
个整数a1 a2 ... an
,其中ai
表示从糖果前端开始第i
段的口味,每段均1
为单位长度。
对于100%的数据,1<=n<=50000
,1<=ai<=50000
输出一行一个整数表示能买到的糖果的最长长度,且其中不包含相同口味.
5
1 2 3 3 4
3
如果我们买长度为4
的糖果,包含的口味为[1,2,3,3]
,存在了重复。
而长度为3
时,包含的口味为[1,2,3]
,不存在重复。因此长度3
为最长的不存在重复口味糖果长度。
题目乍一看是LeetCode3、无重复字符的最长子串原题,但要注意审题和题目场景,还挺坑的。
题目要求只能从糖果的前端出发开始切一刀,所以无需进行滑窗,只需要判断从起始位置开始的最长无重复子数组即可,故直接使用哈希集合即可完成。
# 题目:【哈希集合】微众银行2023秋招-切糖果
# 作者:闭着眼睛学数理化
# 算法:哈希集合
# 代码有看不懂的地方请直接在群上提问
n = int(input())
nums = list(map(int, input().split()))
hash_set = set()
# 遍历数组nums中的每一个元素num
for num in nums:
# 若num从未出现过,则加入哈希集合中
if num not in hash_set:
hash_set.add(num)
# 若num出现过,则直接退出循环
else:
break
# 退出循环后,哈希集合的长度即为答案
print(len(hash_set))
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] nums = new int[n];
for (int i = 0; i < n; i++) {
nums[i] = scanner.nextInt();
}
Set<Integer> hashSet = new HashSet<>();
int count = 0;
for (int num : nums) {
if (!hashSet.contains(num)) {
hashSet.add(num);
count++;
} else {
break;
}
}
System.out.println(count);
}
}
#include <iostream>
#include <unordered_set>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> nums(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
unordered_set<int> hashSet;
int count = 0;
for (int num : nums) {
if (hashSet.find(num) == hashSet.end()) {
hashSet.insert(num);
count++;
} else {
break;
}
}
cout << count << endl;
return 0;
}
时间复杂度:O(N)
。最差的情况是遍历整个数组。
空间复杂度:O(N)
。哈希集合所需空间。