当前位置: 首页 > news >正文

算法基础学习Day5(双指针、动态窗口)

在这里插入图片描述

文章目录

  • 1.题目
  • 2.题目解答
    • 1.四数之和
      • 题目及题目解析
      • 算法学习
      • 代码提交
    • 2.长度最小的子数组
      • 题目及题目解析
      • 滑动窗口的算法学习
        • 方法一:单向双指针(暴力解法)
        • 方法二:同向双指针(滑动窗口)
      • 代码提交

1.题目

  1. 18. 四数之和 - 力扣(LeetCode)
  2. 209. 长度最小的子数组 - 力扣(LeetCode)

2.题目解答

1.四数之和

题目及题目解析

1733707634422

算法学习

1733710613086

1733710932483

去重:

  1. 外层固定的数要跳过相同的数
  2. 内层固定的数也要跳过相同的数
  3. left和right也要跳过相同的数

这部分的代码如下:

int i = 0;
while (i < nums.size() - 1)
{int j = i + 1;while (j < nums.size() - 1){int left = j + 1;int right = nums.size() - 1;long long int tmp = (long long int)target - nums[i] - nums[j];while (left < right){if (nums[left] + nums[right] > tmp){right--;}else if (nums[left] + nums[right] < tmp){left++;}else{v.push_back(nums[i]);v.push_back(nums[left]);v.push_back(nums[right]);v.push_back(nums[j]);vv.push_back(v);v.clear();left++;right--;while (left < right && nums[left] == nums[left - 1]){left++;}while (left < right && nums[right] == nums[right + 1]){right--;}}}j++;while (j < nums.size() - 1 && nums[j] == nums[j - 1]){j++;}}i++;while (i < nums.size() - 1 && nums[i] == nums[i - 1]){i++;}
}

代码提交

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> vv;vector<int> v;sort(nums.begin(),nums.end());int i = 0;while(i<nums.size()-1){int j =i+1;while(j<nums.size()-1){int left =j+1;int right=nums.size()-1;long long int tmp = (long long int)target-nums[i]-nums[j];while(left<right){if(nums[left]+nums[right]>tmp){right--;}else if(nums[left]+nums[right]<tmp){left++;}else{v.push_back(nums[i]);v.push_back(nums[left]);v.push_back(nums[right]);v.push_back(nums[j]);vv.push_back(v);v.clear();left++;right--;while(left<right&&nums[left]==nums[left-1]){left++;}while(left<right&&nums[right]==nums[right+1]){right--;}}}j++;while(j<nums.size()-1&&nums[j]==nums[j-1]){j++;}}i++;while(i<nums.size()-1&&nums[i]==nums[i-1]){i++;}}return vv;}
};

2.长度最小的子数组

题目及题目解析

1733713068683

滑动窗口的算法学习

方法一:单向双指针(暴力解法)

直接定义两个指针从前向后一次遍历,将所有的结果列举出来,直接进行求解

解法如下:

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int ret = INT_MAX;int n = nums.size();// 枚举出所有满⾜和⼤于等于 target 的⼦数组[start, end]// 由于是取到最⼩,因此枚举的过程中要尽量让数组的⻓度最⼩// 枚举开始位置for (int start = 0; start < n; start++) {int sum = 0; // 记录从这个位置开始的连续数组的和// 寻找结束位置for (int end = start; end < n; end++) {sum += nums[end]; // 将当前位置加上if (sum >= target) // 当这段区间内的和满⾜条件时{// 更新结果,start 开头的最短区间已经找到ret = min(ret, end - start + 1);break;}}}// 返回最后结果return ret == INT_MAX ? 0 : ret;}
};

1733726185959

方法二:同向双指针(滑动窗口)

我们在使用暴力解法的时候发现

right指针没有必要每次都进行回退

可以让其一直保持在原有位置不变:

1733726477465

1733726690257

这也就是滑动窗口

当暴力解法两个指针都不回退且要对一部分的区间进行管理,就可以使用双指针解法

解法步骤如下:

初始化部分:

  1. 初始化窗口

    1733726928339

循环部分:

  1. 进窗口

    1733727292329

  2. 判断是否出窗口(同时要记录值)

    1733727417480

  3. 进窗口

    1733727664312

  4. 判断是否出窗口(同时要记录值)

    1733727797087

    重复这两个步骤就可以得出我们想要的结果了

    写成代码如下:

    int left = 0, right = 0;
    int sum = 0;
    int len = INT_MAX;
    for (;right < nums.size();right++)
    {sum += nums[right];while (sum >= target){len = min(len, right - left + 1);sum -= nums[left++];}
    }
    

代码提交

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int left =0,right =0;int sum =0;int len = INT_MAX;for(;right<nums.size();right++){sum += nums[right];while(sum>=target){len = min(len,right-left+1);sum -= nums[left++];}}return len==INT_MAX?0:len;}
};
http://www.lryc.cn/news/500928.html

相关文章:

  • docker 部署 mysql 9.0.1
  • 关于小标join大表,操作不当会导致笛卡尔积,数据倾斜
  • SpringMVC全局异常处理
  • 出海服务器可以用国内云防护吗
  • 从零开始的使用SpringBoot和WebSocket打造实时共享文档应用
  • Ant Design Pro实战--day01
  • pcl点云库离线版本构建
  • 字节高频算法面试题:小于 n 的最大数
  • ElasticSearch常见面试题汇总
  • Spring Boot如何实现防盗链
  • 工作中常用springboot启动后执行的方法
  • 力扣-图论-3【算法学习day.53】
  • Linux上的C语言编程实践
  • 芝法酱学习笔记(1.3)——SpringBoot+mybatis plus+atomikos实现多数据源事务
  • 【计算机网络】实验12:网际控制报文协议ICMP的应用
  • 收缩 tempdb 数据库
  • kubesphere搭建 postgres15
  • 解决npm问题用到的资源,错误原因和方法
  • 【uni-app 微信小程序】新版本发布提示用户进行更新
  • Redis性能优化18招
  • ElasticSearch 与向量数据库的结合实践:突破亿级大表查询瓶颈20241204
  • C#实现一个HttpClient集成通义千问-流式输出内容提取
  • 微信小程序后台搭建—node+mysql
  • 断点续传+测试方法完整示例
  • C# 中的静态构造函数和实例构造函数的区别
  • 如何在UI自动化测试中创建稳定的定位器?
  • 【5G】5G技术组件 5G Technology Components
  • 四十一:Web传递消息时的编码格式
  • 【细如狗】记录一次使用MySQL的Binlog进行数据回滚的完整流程
  • 什么是云原生数据库 PolarDB?