题目来源
- leetcode:904. 水果成篮
题目描述
题目解析
题意
题意从任意位置开始,若最多只能收集两种水果,问最多能收集多少个水果。
这道题目可以理解为求只包含两种元素的最长连续子序列,和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 | 哈希 |