题目来源
题目描述
题目解析
题意
题意从任意位置开始,若最多只能收集两种水果,问最多能收集多少个水果。
这道题目可以理解为求只包含两种元素的最长连续子序列,和leetcode:159.最多有两个不同字符的最长子串几乎一摸一样。唯一不同的是这里是用数字表示不同的种类
实现
思路和159题也一样,用滑动窗口求解。求最长滑动窗口长度
用一个map,key为字符,value为字符出现次数。
class Solution {
public:
int totalFruit(vector<int>& tree) {
int res = 0, start = 0, n = tree.size();
unordered_map<int, int> fruitCnt;
for (int i = 0; i < n; ++i) {
++fruitCnt[tree[i]];
while (fruitCnt.size() > 2) {
if (--fruitCnt[tree[start]] == 0) {
fruitCnt.erase(tree[start]);
}
++start;
}
res = max(res, i - start + 1);
}
return res;
}
};
用一个map,key为字符,value为字符最新的坐标
class Solution {
public:
int totalFruit(vector<int>& tree) {
int res = 0, start = 0, n = tree.size();
std::unordered_map<int, int> fruitPos;
for (int i = 0; i < n; ++i) {
fruitPos[tree[i]] = i;
while (fruitPos.size() > 2){
if(fruitPos[tree[start]] == start){
fruitPos.erase(tree[start]);
}
start++;
}
res = std::max(res, i - start + 1);
}
return res;
}
};
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int i = 0; //滑动窗口左边界
int sub_len = 0; //子序列长度
int fruit_counter = 0; //篮子中的水果种类数
int len = fruits.size();
std::unordered_map<int, int> basket;//创建篮子
for (int j = 0; j < len; ++j) {
if(basket[fruits[j]] == 0){
fruit_counter++;
}
basket[fruits[j]]++;
//如果篮子中的水果数目超过两种,则需要移动左边界,对应从子序列中删去水果的value要减一
for (; fruit_counter > 2; ++i) {
basket[fruits[i]]--;
//若对应水果key的value变为0,说明篮子里已经没有这种水果了,水果种类要对应变化
if (basket[fruits[i]] == 0) {
fruit_counter--;
}
}
//在第二个for循环结束后,篮子中的水果一定满足题意要求,此时更新子序列长度
sub_len = max(sub_len, j - i + 1);
}
return sub_len;
}
};
类似题目
题目 | 思路 |
---|---|
leetcode:159.最多有两个不同字符的最长子串 | 滑动窗口 |
leetcode:904. 水果成篮 | 滑动窗口 |
leetcode:76. 最小子串:字符串s2覆盖s1的所有子串的最小子串 Minimum Window Substring | 哈希 |