LeetCode·904.水果成篮·滑动窗口

链接:https://leetcode.cn/problems/fruit-into-baskets/solution/hd-by-xun-ge-v-nyer/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 

题目LeetCode·904.水果成篮·滑动窗口_第1张图片

示例LeetCode·904.水果成篮·滑动窗口_第2张图片

思路

解题思路
滑动窗口也可以理解为双指针法的一种!只不过这种解法更像是一个窗口的移动,所以叫做滑动窗口更适合一些。

实现滑动窗口,主要确定如下三点:

  • 窗口内是什么?
  • 如何移动窗口的起始位置?
  • 如何移动窗口的结束位置?


对于本题:

  • 窗口-> 果树的类型
  • 如何移动窗口的起始位置-> 数组开始位置即可设置为滑动窗口开始的位置,当窗口内果树类型大于2时,窗口向前移动,也就是收缩窗口,收缩到什么时候为止呢?果树类型小于2
  • 如何移动窗口的结束位置-> 遍历数组的指针即可设置为滑动窗口结束的位置,当窗口内果树类型小于等于2时,窗口向前移动,也就是扩大窗口,扩大到什么时候为止呢?果树类型大于2

具体实现
值得注意的是,如何高效快捷的统计窗口中果树的类型,以及同种类型果树在当前窗口存在多少呢?因为我们在收缩窗口的时候,要收缩到果树类型小于2才能停止。面对这种同类型数量统计问题或者是查重问题,哈希表是不二之选。我们定义一个简易的哈希表,以树的类型为键,转换到我们简易哈希表中就是对应下标,然后记录相同类型树的数目即可

详细可看代码,注释超级详细

代码

#define MAX(a, b) ((a) > (b) ? (a) : (b))

int totalFruit(int* fruits, int fruitsSize){
    int ans[100000] = {0};//简易哈希表,并初始化
    int max = INT_MIN;//记录窗口最大值
    int sum = 0;//记录种类
    for(int i = 0, j = 0; i < fruitsSize; i++)//遍历数组
    {
        if(ans[fruits[i]] == 0)//当前树种类为0个,说明是新的种类
        {
            sum++;//窗口种类数目+1
        }
        ans[fruits[i]]++;//相同类型树数目+1
        while(sum > 2)//窗口种类数目》2 需要收缩窗口
        {
            ans[fruits[j]]--;
            if(ans[fruits[j]] == 0)//收缩到任意类型数目为0为止
            {
                sum--;
            }
            j++;
        }
        max = MAX(max, i-j+1);
    }
    return max;
}

作者:xun-ge-v
链接:https://leetcode.cn/problems/fruit-into-baskets/solution/hd-by-xun-ge-v-nyer/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(LeetCode刷题笔记,leetcode,算法,职场和发展)