Problem: 904. 水果成篮
思路
需要找到连续的最多两种类型的最长序列
通过例子讲解思路:34335,left=0,mid=1,new_mid=2
定义:现有三个下标left,mid,new_mid;其中left和mid分别指为两种特定的类型;new_mid是当前数据与现有两种类型都不匹配时,left应该移动到哪里
最开始有两种类型分别为3,4(对应下标left=0,mid=1),之后当新的类型5出现时,与现有两种类型不同,因此需要对类型进行调整,即移动left以及mid(left移动到new_mid(=2)位置上,mid移动到类型5所在的位置(mid=4)上)
解题方法
由于有两种类型,需要逐步完善这两种类型:
- 只有一个类型时,当前位置和保存的一个类型不同,则扩充第二个类型
- 当前位置和保存的两个类型不同,重新调整类型(即移动left以及mid)
易错点:第2.中(与现有类型都不匹配情况)需要全面考虑,考虑的内容已经放到代码注释当中
复杂度
时间复杂度:
添加时间复杂度, 示例: O ( n ) O(n) O(n)
空间复杂度:
添加空间复杂度, 示例: O ( 1 ) O(1) O(1)
Code
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int left = 0, right = 0;
int type = 1, mid = left, max_result = 1, new_mid=left; // !!! left和mid分别为两种特定的类型, new_mid是当类型都不匹配时,left应该移动到哪里
for (; right < fruits.size(); right++){
if ((fruits[right] != fruits[mid] || fruits[right] != fruits[left]) && type == 1){ // 当前位置和保存的一个类型不同,扩充第二个类型
type--;
mid = right; // 保存第二个不同值位置
new_mid = mid;
}
else if(fruits[right] != fruits[mid] && fruits[right] != fruits[left] && type == 0){ // 当前位置和保存的两个类型不同,重新调整类型
left = new_mid;
mid = right;
}
if(fruits[right] == fruits[mid] || fruits[right] == fruits[left]){
max_result = max(max_result, right-left+1);
// 确定当类型都不匹配时,从已经匹配的位置上找left移动的位置new_mid
if(fruits[right] == fruits[left] && fruits[right] != fruits[new_mid]){ // 出现12111情况,left:0, mid:1, new_mid:2
new_mid = right;
}else if(fruits[right] == fruits[mid] && fruits[right] != fruits[new_mid]){ // 出现121222情况,left:0, mid:1, new_mid:3
new_mid = right;
}
}
// cout<<left<<" "<<right<<" mid:"<<mid<<" new:"<<new_mid<<" type:"<<type<<" | "<<max_result<<endl;
}
return max_result;
}
};