【滑动窗口】“正难则反法” 解决最小操作数的问题

2023-10-18 17:12

本文主要是介绍【滑动窗口】“正难则反法” 解决最小操作数的问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

Problem: 1658. 将 x 减到 0 的最小操作数

文章目录

  • 题目解析
  • 算法原理分析
  • Code
  • 复杂度

题目解析

首先我们来解读一下本题的题目含义

  • 题目会给到我们一个整数数组和一个整数x,我们可以从左侧,也可以从右侧去减,只要让这个x最终减到【0】即可。
  • 不过呢既然可以从左边也可以从右边减的话就一定存在多种方案,我们所需要的话是操作次数最少的那次,看到下面我列出来的两种情况,很明显第二种方法 从右侧删去两个数据更加优的

1.jpg

算法原理分析

接下去我们来介绍一下本题的算法原理

  • 通过刚才的分析相信很多小伙伴认为本题的题目意思并不是很难理解,但是呢想找到对应的解决方案还是比较困难的,在这里的话教大家一种方法叫做 “正难则反法"
  • 题目中要我们去找的是左右两侧的 最小操作数,但是呢这并不好计算,于是我们可以换个思路,将左侧的数据看做是一个整体,记为a;将右侧的数据看做是一个整体,记为b;那么我们可以得出a + b = x
  • 既然左右两侧的是x的话,那么中间的一段就是sum - x。而且既然两边需要最短的话,中间我们要找的就是【最长的那一段】

2.jpg

  • 因此经过上面的步步分析,我们便将题目的意思转换为了去找 数组里面最长子数组的长度,而且它们的和即为sum - x的结果。不过最后我们要返回的结果可不是这个长度len,而是n - len

3.jpg

  • 本题我们还是考虑使用滑动窗口来进行求解,因为滑动窗口本身就是基于【双指针】的,所以读者在看此文的时候可以先看看我『双指针』的专栏题解
  • 我们的right指针还是一样作为向后遍历并进行计数累加的指针,当其没有达到target的时候就继续去作累加的操作,这相当于是【进窗口】的操作。当其到中间这个点的时候此时sum的值只会是 大于或者等于target
  • sum == target 的时候呢便去做更新长度的操作。当sum > target的时候我们就要去考虑【出窗口】的操作,将左侧的left指针所指向的内容从我们所累加的和中减去,然后还需要执行left++让其继续后移

4.jpg

那有同学问:right还需要回来吗,还是持续后移呢?

  • 我们来探讨一下这个问题,因为在中间这个点的时候sum >= target,那从最左侧到这个点前面一个点的总和是< target的,那如果我们使用暴力解法的话在left向后移动的时候,此时如果right再回来的话,其实是没有必要了,因为left++执行了出窗口的操作后,这个sum就更为小了,此时让right--再左移的话只会更小
  • 所以我们的和这个right是不需要回来的,它只会在那个== target的位置或者是> target的位置

5.jpg

💬 最后的代码详解我们马上来看看看【code】部分,不过读者可以根据算法原理的解读自己试着写写看

Code

对于代码而言的话读者基本上就是根据我们前面所描述的去进行书写即可,还有一些细节地方需要注意

  • 题目中给到的提示这一块,即数组里面所有的数据都是大于1的,那么我们数组中找这个target的时候是不会出现负数这种情况的,所以若是遇到这种情况的,我们直接return -1即可

6.jpg

以下是整体的代码详解:


class Solution {
public:int minOperations(vector<int>& nums, int x) {int n = nums.size();int sum1 = 0;    // 用于先行求出整个数组的和int sum2 = 0;    // 用于遍历数组时的累加int ret = -1;for(int a : nums)   sum1 += a; int target = sum1 - x;      // 减去两端的数据后中间的和// 处理细节:数组中不会存在负数, 若存在的话则表示找不到if(target < 0)  return -1;for(int left = 0, right = 0; right < n; ++right){// 1.进窗口sum2 += nums[right];// 累加和超过target则开始出窗口while(sum2 > target){// 2.出窗口sum2 -= nums[left++]; }// 3.更新结果if(sum2 == target)ret = max(ret, right - left + 1);}if(ret == -1)   return ret;elsereturn n - ret;    // 减去最长的子串即为最小操作数}
};

下面则是执行的结果:

7.jpg

复杂度

最后我们来谈一下复杂度这一块

  • 时间复杂度:

对于时间复杂度我们在一开始做了遍历,去累加数组中的和,后面呢又去遍历了一下这个数组,结合一下最后的复杂度还是 O ( n ) O(n) O(n)

  • 空间复杂度:

对于空间复杂度来说,我们并没有开辟出多余的空间,即为 O ( 1 ) O(1) O(1)

在这里插入图片描述

这篇关于【滑动窗口】“正难则反法” 解决最小操作数的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/234014

相关文章

Springboot3统一返回类设计全过程(从问题到实现)

《Springboot3统一返回类设计全过程(从问题到实现)》文章介绍了如何在SpringBoot3中设计一个统一返回类,以实现前后端接口返回格式的一致性,该类包含状态码、描述信息、业务数据和时间戳,... 目录Spring Boot 3 统一返回类设计:从问题到实现一、核心需求:统一返回类要解决什么问题?

解决idea启动项目报错java: OutOfMemoryError: insufficient memory

《解决idea启动项目报错java:OutOfMemoryError:insufficientmemory》:本文主要介绍解决idea启动项目报错java:OutOfMemoryError... 目录原因:解决:总结 原因:在Java中遇到OutOfMemoryError: insufficient me

maven异常Invalid bound statement(not found)的问题解决

《maven异常Invalidboundstatement(notfound)的问题解决》本文详细介绍了Maven项目中常见的Invalidboundstatement异常及其解决方案,文中通过... 目录Maven异常:Invalid bound statement (not found) 详解问题描述可

idea粘贴空格时显示NBSP的问题及解决方案

《idea粘贴空格时显示NBSP的问题及解决方案》在IDEA中粘贴代码时出现大量空格占位符NBSP,可以通过取消勾选AdvancedSettings中的相应选项来解决... 目录1、背景介绍2、解决办法3、处理完成总结1、背景介绍python在idehttp://www.chinasem.cna粘贴代码,出

SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)

《SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)》本文总结了SpringBoot项目整合Kafka启动失败的常见错误,包括Kafka服务器连接问题、序列化配置错误、依赖配置问题、... 目录一、Kafka服务器连接问题1. Kafka服务器无法连接2. 开发环境与生产环境网络不通二、序

SpringSecurity中的跨域问题处理方案

《SpringSecurity中的跨域问题处理方案》本文介绍了跨域资源共享(CORS)技术在JavaEE开发中的应用,详细讲解了CORS的工作原理,包括简单请求和非简单请求的处理方式,本文结合实例代码... 目录1.什么是CORS2.简单请求3.非简单请求4.Spring跨域解决方案4.1.@CrossOr

nacos服务无法注册到nacos服务中心问题及解决

《nacos服务无法注册到nacos服务中心问题及解决》本文详细描述了在Linux服务器上使用Tomcat启动Java程序时,服务无法注册到Nacos的排查过程,通过一系列排查步骤,发现问题出在Tom... 目录简介依赖异常情况排查断点调试原因解决NacosRegisterOnWar结果总结简介1、程序在

解决java.util.RandomAccessSubList cannot be cast to java.util.ArrayList错误的问题

《解决java.util.RandomAccessSubListcannotbecasttojava.util.ArrayList错误的问题》当你尝试将RandomAccessSubList... 目录Java.util.RandomAccessSubList cannot be cast to java.

Apache服务器IP自动跳转域名的问题及解决方案

《Apache服务器IP自动跳转域名的问题及解决方案》本教程将详细介绍如何通过Apache虚拟主机配置实现这一功能,并解决常见问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录​​问题背景​​解决方案​​方法 1:修改 httpd-vhosts.conf(推荐)​​步骤

java反序列化serialVersionUID不一致问题及解决

《java反序列化serialVersionUID不一致问题及解决》文章主要讨论了在Java中序列化和反序列化过程中遇到的问题,特别是当实体类的`serialVersionUID`发生变化或未设置时,... 目录前言一、序列化、反序列化二、解决方法总结前言serialVersionUID变化后,反序列化失