赞
踩
//滑动窗口+哈希表,一次遍历O(n) //难点:如何用判断边界的移动时机,应该可以自己实现。 //right和left不一定相同,记录窗口中两个元素,边界扩张时,如果出现新元素,fruits[right]是新元素,记录新元素。 //当kind[0]=kind[1],新元素顶替kind的一员。 //左边界left++,直到fruits[left-1]的hash值=0,说明一个元素离开窗口。 int totalFruit(int* fruits, int fruitsSize) { int hash[100001] = { 0 };//hash集合 if (1 == fruitsSize) {//由题意,边界处理 return 1; } else if (2 == fruitsSize) {//同样边界处理 return 2; } int left = 0, right = 1;//维护左右窗口 int kind[2] = { 0 };//最多关注两种水果 //kind存水果种类,对应hash++ kind[0] = fruits[left]; hash[kind[0]]++; kind[1] = fruits[right]; hash[kind[1]]++; int ans = 0;//答案 while (right < fruitsSize - 1) {//右边界没到fruitsSize hash[fruits[++right]]++;//右边界右移,新水果hash++ if (fruits[right] != kind[0] && fruits[right] != kind[1]) {//right遇到新水果 if (kind[0] == kind[1]) {//果篮是相同水果, kind[1] = fruits[right];//kind[1]变成新水果 } else {//果篮是不同水果 while (1) {//左边界循环右移 hash[fruits[left++]]--;//左水果--,左边界++ if (0 == hash[fruits[left - 1]]) {//原先的左水果不在滑动窗口了 if (fruits[left - 1] == kind[1]) {//离开的左水果是kind[1] kind[1] = kind[0]; kind[0] = fruits[right];//kind[0]变新水果 } else {//离开的左水果是kind[0] kind[0] = kind[1];//kind[0]变kind[1] kind[1] = fruits[right];//kind[1]变新水果 } break;//跳出循环! } } } } if (kind[0] == kind[1]) {//果篮只有一种元素 ans = ans < hash[kind[0]] ? hash[kind[0]] : ans;//取较大值 } else {//果篮有两种元素。 ans = ans < hash[kind[0]] + hash[kind[1]] ? hash[kind[0]] + hash[kind[1]] : ans; } } return ans; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。