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

本文介绍了一种算法来解决水果成篮问题,目标是找到给定数组中连续的最多两种类型的最长序列。通过举例和详细步骤解释了如何动态维护两种类型的下标,以及如何处理新类型出现时的类型调整,确保时间复杂度为O(n)且空间复杂度为O(1)。
摘要由CSDN通过智能技术生成

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;
}
};
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值