滑动窗口算法&删除排序数组中重复项

简介: 滑动窗口算法&删除排序数组中重复项

LeetCode

滑动窗口算法

LeetCode第1176题:

你的好友是一位健身爱好者。前段日子,他给自己制定了一份健身计划。现在想请你帮他评估一下这份计划是否合理。
他会有一份计划消耗的卡路里表,其中 calories[i] 给出了你的这位好友在第 i 天需要消耗的卡路里总量。
为了更好地评估这份计划,对于卡路里表中的每一天,你都需要计算他 「这一天以及之后的连续几天」 (共 k 天)内消耗的总卡路里 T:
如果 T < lower,那么这份计划相对糟糕,并失去 1 分; 
如果 T > upper,那么这份计划相对优秀,并获得 1 分;
否则,这份计划普普通通,分值不做变动。
请返回统计完所有 calories.length 天后得到的总分作为评估结果。
注意:总分可能是负数。

示例一

输入:calories = [1,2,3,4,5], k = 1, lower = 3, upper = 3
输出:0
解释:calories[0], calories[1] < lower 而 calories[3], calories[4] > upper, 总分 = 0.

示例二

输入:calories = [3,2], k = 2, lower = 0, upper = 1
输出:1
解释:calories[0] + calories[1] > upper, 总分 = 1.

示例三

输入:calories = [6,5,0,0], k = 2, lower = 1, upper = 5
输出:0
解释:calories[0] + calories[1] > upper, calories[2] + calories[3] < lower, 总分 = 0.

看完这个题目基本上明白题意了,看了一下题目的评论,才知道这是滑动窗口算法。再百度一下滑动窗口算法。发现有一篇文章讲的很清楚。

https://blog.csdn.net/sty945/article/details/79846516

其中提到对于这个算法有一个很经典的题:给定一个大小为n的整形数组,计算长度为k的子数组的最大值。例如:

{1,2,3,4,5,6}   
    //有这样一个数组,求长度为3的子数组之和最大为多少
    //对于这个数组来说数组之和最大并且长度为3的子数组肯定就是{4,5,6}
    //那么用代码实现的过程就是滑动窗口算法实现的过程

代码:

int maxSum(int arr[], int n, int k)
    //arr为原数组{1,2,3,4,5,6},n为数组长度,k为子数组长度
    {
    if (n < k)//如果原数组为{1,2}长度n=2;求长度k=3的子数组没有意义。
    {
        cout << "Invaild";
        return -1;
    }
    int max_sum = 0;
    for (int i=0; i<k; i++)//先求第一个窗格的和
    {
        max_sum += arr[i];
    }
    int windows_sum = max_sum;//max_sum=6
    for (int i=k; i<n; i++)//往下求后面的窗格
    {
        /*          
            i=k=3       
            windows_sum=windows_sum+arr[3]-arr[0]=6+4-1=9
            {2,3,4}=9;
            相当于向后移动求和
        */
        windows_sum += arr[i] - arr[i - k];
        max_sum = max(max_sum, windows_sum);
    }
    return max_sum;
    }

那么对于上面健身的题也是一样的道理,只是多了几个比较再加一个分数。

代码:

class Solution {
    public int dietPlanPerformance(int[] calories, int k, int lower, int upper) {
        if(calories.length<k)//如果数组长度小于k没有意义
        {
            return 0;
        }
        int ans=0;
        int sum=0;
        for(int i=0;i<k;i++){//先求第一个窗格
            sum+=calories[i];
        }
        if(sum<lower){ans--;}//做判断定分数
        if(sum>upper){ans++;}
        for(int i=k;i<calories.length;i++){//求后面的窗格
            sum+=calories[i]-calories[i-k];
            if(sum<lower){ans--;}//再来判断分数
            if(sum>upper){ans++;} 
        }
        return ans;//返回分数
    }
}

LeetCode第26题:删除排序数组中重复项

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例

给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。

这道题现在想起来不难,但是第一次看见还是卡在那里,直接看官方的代码

代码:

public int removeDuplicates(int[] nums) {
    if (nums.length == 0) return 0;
    int i = 0;
    for (int j = 1; j < nums.length; j++) {
        if (nums[j] != nums[i]) {
            i++;
            nums[i] = nums[j];
        }
    }
    return i + 1;
}

官方讲解

数组完成排序后,我们可以放置两个指针 i 和 j,其中 i 是慢指针,而 j 是快指针。只要 nums[i] = nums[j],我们就增加 j 以跳过重复项。
当我们遇到 nums[j]!=nums[i]时,跳过重复项的运行已经结束,因此我们必须把它(nums[j])的值复制到 nums[i+1]。
然后递增i,接着我们将再次重复相同的过程,直到 j 到达数组的末尾为止。

                                                                           

相关文章
|
4天前
|
存储 算法 调度
【数据结构与算法】详解循环队列:基于数组实现高效存储与访问
【数据结构与算法】详解循环队列:基于数组实现高效存储与访问
|
3天前
|
算法 Java 调度
Java数据结构与算法:拓扑排序
Java数据结构与算法:拓扑排序
|
4天前
|
算法 搜索推荐 C++
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
13 0
|
4天前
|
存储 算法 编译器
【数据结构与算法】使用数组实现栈:原理、步骤与应用
【数据结构与算法】使用数组实现栈:原理、步骤与应用
|
5天前
|
存储 算法 Java
Java数据结构与算法:线性数据结构之数组
Java数据结构与算法:线性数据结构之数组
|
8天前
|
人工智能 算法 搜索推荐
蓝桥杯宝藏排序题目算法(冒泡、选择、插入)
以下是内容的摘要: 本文介绍了三种排序算法:冒泡排序、选择排序和插入排序。冒泡排序通过不断交换相邻的逆序元素逐步排序,最坏情况下需要 O(n^2) 次比较。选择排序在每轮中找到剩余部分的最小元素并放到已排序序列的末尾,同样具有 O(n^2) 时间复杂度。插入排序则是将每个元素插入到已排序序列的正确位置,时间复杂度也是 O(n^2),但空间复杂度为 O(1)。
|
9天前
|
人工智能 算法 BI
【洛谷 P1803】凌乱的yyy _ 线段覆盖 题解(贪心算法+结构体排序)
**线段覆盖问题**: YYY 想在 NOIP 前参加最多比赛。给定 $n$ 场比赛的开始和结束时间,每场比赛必须连续且不能冲突。输入包含每场比赛的时间段,输出最多可参加的比赛数。$20\%$ 数据 $n\leq10$,$50\%$ 数据 $n\leq10^3$,$100\%$ 数据 $n\leq10^6$。解决方案:按结束时间排序比赛,若当前比赛开始时间晚于上一个结束时间,则计数加一。样例输入:3 场比赛,输出:2。AC C++ 代码实现了此算法。
11 0
|
4天前
|
机器学习/深度学习 自然语言处理 算法
m基于深度学习的OFDM+QPSK链路信道估计和均衡算法误码率matlab仿真,对比LS,MMSE及LMMSE传统算法
**摘要:** 升级版MATLAB仿真对比了深度学习与LS、MMSE、LMMSE的OFDM信道估计算法,新增自动样本生成、复杂度分析及抗频偏性能评估。深度学习在无线通信中,尤其在OFDM的信道估计问题上展现潜力,解决了传统方法的局限。程序涉及信道估计器设计,深度学习模型通过学习导频信息估计信道响应,适应频域变化。核心代码展示了信号处理流程,包括编码、调制、信道模拟、降噪、信道估计和解调。
26 8
|
6天前
|
算法
基于GA遗传优化的混合发电系统优化配置算法matlab仿真
**摘要:** 该研究利用遗传算法(GA)对混合发电系统进行优化配置,旨在最小化风能、太阳能及电池储能的成本并提升系统性能。MATLAB 2022a用于实现这一算法。仿真结果展示了一系列图表,包括总成本随代数变化、最佳适应度随代数变化,以及不同数据的分布情况,如负荷、风速、太阳辐射、弃电、缺电和电池状态等。此外,代码示例展示了如何运用GA求解,并绘制了发电单元的功率输出和年变化。该系统原理基于GA的自然选择和遗传原理,通过染色体编码、初始种群生成、适应度函数、选择、交叉和变异操作来寻找最优容量配置,以平衡成本、效率和可靠性。
|
7天前
|
机器学习/深度学习 算法
基于鲸鱼优化的knn分类特征选择算法matlab仿真
**基于WOA的KNN特征选择算法摘要** 该研究提出了一种融合鲸鱼优化算法(WOA)与K近邻(KNN)分类器的特征选择方法,旨在提升KNN的分类精度。在MATLAB2022a中实现,WOA负责优化特征子集,通过模拟鲸鱼捕食行为的螺旋式和包围策略搜索最佳特征。KNN则用于评估特征子集的性能。算法流程包括WOA参数初始化、特征二进制编码、适应度函数定义(以分类准确率为基准)、WOA迭代搜索及最优解输出。该方法有效地结合了启发式搜索与机器学习,优化特征选择,提高分类性能。