Bootstrap

[Leetcode] 904. 水果成篮 —— 滑动窗口

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)上)

解题方法

由于有两种类型,需要逐步完善这两种类型:

  1. 只有一个类型时,当前位置和保存的一个类型不同,则扩充第二个类型
  2. 当前位置和保存的两个类型不同,重新调整类型(即移动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;
}
};
;