刷题11 双指针

一、同向双指针


209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3]
输入:target = 4, nums = [1,4,4]
输出:1
int minSubArrayLen(int target, int* nums, int numsSize) {int l=0,r=0;int sum=0;int ans=INT_MAX;while(r<numsSize){sum+=nums[r];while(sum>=target){ans=fmin(ans,r-l+1);sum-=nums[l];l++;}r++;}return ans==INT_MAX?0:ans;
}


713. 乘积小于 K 的子数组

给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的乘积严格小于 k 的连续子数组的数目。

输入:nums = [10,5,2,6], k = 100
输出:8
解释:8 个乘积小于 100 的子数组分别为:[10]、[5]、[2],、[6]、[10,5]、[5,2]、[2,6]、[5,2,6]。
需要注意的是 [10,5,2] 并不是乘积小于 100 的子数组。
int numSubarrayProductLessThanK(int* nums, int numsSize, int k) {int l=0,r=0;int sum=1;int ans=0;while(r<numsSize){sum*=nums[r];//注意此处l不能超过rwhile(l<=r&&sum>=k){sum/=nums[l];l++;}ans+=r-l+1;r++;}return ans;
}


LCR 016. 无重复字符的最长子串

 给定一个字符串 s ,请你找出其中不含有重复字符的 最长连续子字符串 的长度。

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子字符串是 "abc",所以其长度为 3。
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子字符串是 "b"所以其长度为 1。

        此题不是只有字母,因此无法通过,有除字母以外的字符之外出现的话需要用map进行记录。 

int lengthOfLongestSubstring(char * s){if(s=="") return 0;int flag[128]={0};int l=0,r=0;int ans=0;int n=strlen(s);while(r<n){flag[s[r]-'a']++;while(flag[s[r]-'a']>1){flag[s[l]-'a']--;l++;}  if(l<r&&s==' ') l++;ans=fmax(ans,r-l+1);r++;}return ans;
}

        c++版本:

class Solution {
public:int lengthOfLongestSubstring(string s) {int n=s.size();int left=0;int answer=0;set<char> st;for(int right=0;right<n;++right){while(st.find(s[right])!=st.end()){//若集合中已经出现过st.erase(s[left]);//讲其从集合中删去++left;//左指针右移}st.insert(s[right]);//若出现过,则加入集合中answer=max(answer,right-left+1);//更新最大长度}return answer;}
};


1574. 删除最短的子数组使剩余数组有序

 给你一个整数数组 arr ,请你删除一个子数组(可以为空),使得 arr 中剩下的元素是 非递减 的。一个子数组指的是原数组中连续的一个子序列。请你返回满足题目要求的最短子数组的长度。

输入:arr = [1,2,3,10,4,2,3,5]
输出:3
解释:我们需要删除的最短子数组是 [10,4,2] ,长度为 3 。剩余元素形成非递减数组 [1,2,3,3,5] 。
另一个正确的解为删除子数组 [3,10,4] 。
int findLengthOfShortestSubarray(int* arr, int arrSize){int r=arrSize-1;while(r&&arr[r-1]<=arr[r]){r--;}//当前数列已经是递增的if(r==0) return 0;int ans=r;//枚举左区间起点for(int l=0;l==0||arr[l-1]<=arr[l];++l){while(r<arrSize&&arr[r]<arr[l]){r++;}ans=fmin(ans,r-l-1);}return ans;
}


1004. 最大连续1的个数 III

 给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。

输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。
输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。
int longestOnes(int* nums, int numsSize, int k) {int l=0,r=0;int zero=0;int ans=0;while(r<numsSize){if(nums[r]==0) zero++;while(zero>k){if(nums[l]==0) zero--;l++;}ans=fmax(ans,r-l+1);r++;}return ans;
}


1234. 替换子串得到平衡字符串

 有一个只含有 'Q', 'W', 'E', 'R' 四种字符,且长度为 n 的字符串。

假如在该字符串中,这四个字符都恰好出现 n/4 次,那么它就是一个「平衡字符串」。给你一个这样的字符串 s,请通过「替换一个子串」的方式,使原字符串 s 变成一个「平衡字符串」。

你可以用和「待替换子串」长度相同的 任何 其他字符串来完成替换。请返回待替换子串的最小可能长度。如果原字符串自身就是一个平衡字符串,则返回 0

输入:s = "QWER"
输出:0
解释:s 已经是平衡的了。
输入:s = "QQWE"
输出:1
解释:我们需要把一个 'Q' 替换成 'R',这样得到的 "RQWE" (或 "QRWE") 是平衡的。
int balancedString(char* s) {int hash[26]={0};int l=0,r=0;int len=strlen(s);int n=len/4;int ans=len;//记录每个字母出现的次数for(int i=0;i<len;++i){hash[s[i]-'A']++;}//如果满足条件,直接返回0if(hash['Q'-'A']==n&&hash['Q'-'A']==n&&hash['W'-'A']==n&&hash['R'-'A']==n){return 0;}//快指针向前遍历for(r=0;r<len;++r){//快指针每走一步状态更新hash[s[r]-'A']--;//慢指针按条件收缩窗口while(l<=r&&hash['Q'-'A']<=n&&hash['W'-'A']<=n&&hash['E'-'A']<=n&&hash['R'-'A']<=n){//慢指针每走一步状态更新hash[s[l]-'A']++;//记录窗口最值ans=fmin(ans,r-l+1);l++;}}return ans;
}


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

 给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。

输入:nums = [1,1,4,2,3], x = 5
输出:2
解释:最佳解决方案是移除后两个元素,将 x 减到 0 。

方法一:逆向思维+双指针
把问题转换成「从 nums 中移除一个最长的子数组,使得剩余元素的和为 x。换句话说,要从 nums 中找最长的子数组,其元素和等于 s−x,这里 s 为 nums 所有元素之和。

int minOperations(int* nums, int numsSize, int x) {//从nums中移除一个最长的子数组,使得剩余元素的和为xint target=0;for(int i=0;i<numsSize;++i){target+=nums[i];}target-=x;if(target<0) return -1;int l=0,r=0;int ans=-1,sum=0;for(r=0;r<numsSize;++r){sum+=nums[r];while(sum>target){sum-=nums[l];l++;}if(sum==target){ans=fmax(ans,r-l+1);}}return ans<0?-1:numsSize-ans;
}

二、对撞双指针


15. 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;sort(nums.begin(), nums.end());for (int i = 0; i < nums.size(); i++) {// 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了if (nums[i] > 0) {return result;}if (i > 0 && nums[i] == nums[i - 1]) {//去重continue;}int left = i + 1;int right = nums.size() - 1;while (right > left) {if (nums[i] + nums[left] + nums[right] > 0) right--;else if (nums[i] + nums[left] + nums[right] < 0) left++;else {result.push_back(vector<int>{nums[i], nums[left], nums[right]});// 去重逻辑应该放在找到一个三元组之后,对b 和 c去重while (right > left && nums[right] == nums[right - 1]) right--;while (right > left && nums[left] == nums[left + 1]) left++;// 找到答案时,双指针同时收缩right--;left++;}}}return result;}
};


167. 两数之和 II - 输入有序数组

给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列  ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。

以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1  index2

你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。

你所设计的解决方案必须只使用常量级的额外空间。

输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {int *res=malloc(sizeof(int)*2);*returnSize=2;int l=0,r=numbersSize-1;while(l<r){int sum=numbers[l]+numbers[r];if(sum<target){l++;}else if(sum>target){r--;}else{res[0]=l+1;res[1]=r+1;return res;}}return res;
}


11. 盛最多水的容器

 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。

输入:[1,8,6,2,5,4,8,3,7]
输出:49 
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
int maxArea(int* height, int heightSize) {int mmax=0;int i=0,j=heightSize-1;while(i<j){int cur=fmin(height[i],height[j])*(j-i);if(cur>mmax) mmax=cur;if(height[i]<height[j]){i++;}else{j--;}}return mmax;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/666317.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试 JavaScript 框架八股文十问十答第二期

面试 JavaScript 框架八股文十问十答第二期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01;关注专栏后就能收到持续更新&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;其他值到字符串的…

两个重要极限【高数笔记】

【第一个&#xff1a;lim &#xff08;sinx / x&#xff09; 1, x -- > 0】 1.本质&#xff1a; lim &#xff08;sin‘&#xff1f;’ / ‘&#xff1f;’&#xff09; 1, ‘&#xff1f;’ -- > 0&#xff1b;保证‘&#xff1f;’ -- > 0,与趋向无关 2.例题&#x…

【ELK】logstash快速入门

1.概述 1.1.什么是logstash&#xff1f; 之前我们聊了es&#xff0c;并且用docker搭建了一个eskibana的环境。es目前最普遍的用法是用来存储日志的&#xff0c;然后结合kibana对日志做一些可视化的工作。既然要收集日志&#xff0c;就面临着一个问题&#xff1a; 各个系统的…

口味多样的碱水贝果面包,香气饱满松松软软

这两天在吃一款碱趣贝果面包&#xff0c;感觉味道很不错&#xff0c;它是一种加热一下就可以吃的手工面包&#xff0c;口感十分独特。这款面包有着清香有韧性的表皮&#xff0c;里面松软可口&#xff0c;加热后更是香气四溢。 除了标准的原味全麦之外&#xff0c;碱趣贝果面包还…

Python爬虫某云音乐歌手及下载其免费音乐

import os import re import threading import timefrom lxml import etreeimport requests from bs4 import BeautifulSoup from database import MyDataBase from utils import make_user_agent 注意&#xff1a;database和utils是自己写的。没有注释&#xff0c;不懂就问 先…

【大厂AI课学习笔记】1.4 算法的进步(3)关于Hinton

Geoffrey Hinton&#xff1a;深度学习之父的传奇人生与杰出贡献 在人工智能领域&#xff0c;有一位科学家的名字如同星辰般闪耀&#xff0c;他就是Geoffrey Hinton。作为深度学习的奠基人之一&#xff0c;Hinton的生涯充满了创新、突破和对未知的不懈探索。他的贡献不仅重塑了…

SpringBoot数据访问复习

SpringBoot数据访问复习 数据访问准备 引入jdbc所需要的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency> 原理分析 导入的启动器引入了两个…

【年度盛会征稿】第二届全国精准营养与生命健康创新大会(PNHIC 2024)

第二届全国精准营养与生命健康创新大会&#xff08;PNHIC 2024&#xff09; 【高层次专家齐聚交流&#xff0c;年度盛会&#xff01;】 近年来&#xff0c;人们对营养与健康愈加关注&#xff0c;精准营养学研究也成为一个快速发展的热点领域。“精准营养”研究借助多组学、可…

Qt程序设计-运行脚本文件.bat

Qt程序设计-运行脚本文件.bat 本文演示如何实现Qt运行脚本文件.bat 创建一个脚本文件 在D盘,新建一个test.txt文件,将下面的拷入,然后更改后缀名称为bat @echo off set filename=newfile.txt if not exist %filename% (echo This is a new file > %filename% ) else …

Android Studio开发配置(gradle配置)

文章目录 plugin:com.android.applicationgradle换源gradle下载AVD启动电脑蓝屏 刚安装android studio的话&#xff0c;如果直接创建项目&#xff0c;基本gradle编译不过去&#xff0c;会报错。 plugin:com.android.application 最开始我一直报错找不到插件&#xff0c;因为我…

MySQL进阶45讲【13】为什么表数据删掉一半,表文件大小不变?

1 前言 有些小伙伴在删数据库数据时&#xff0c;会产生一个疑问&#xff0c;我的数据库占用空间大&#xff0c;我把一个最大的表删掉了一半的数据&#xff0c;怎么表文件的大小还是没变&#xff1f; 那么这篇文章&#xff0c;就介绍一下数据库表的空间回收&#xff0c;看看如…

【链表】-Lc146-实现LRU(巧妙借助LinkedHashMap)

写在前面 最近想复习一下数据结构与算法相关的内容&#xff0c;找一些题来做一做。如有更好思路&#xff0c;欢迎指正。 目录 写在前面一、场景描述二、具体步骤1.环境说明2.代码 写在后面 一、场景描述 运用你所掌握的数据结构&#xff0c;设计和实现一个 LRU (Least Recently…

Linux Rootkit:内核 5.7+ 的新方法

Linux Rootkit&#xff1a;内核 5.7 的新方法 文章目录 [Linux Rootkit&#xff1a;内核 5.7 的新方法](https://xcellerator.github.io/posts/linux_rootkits_11/)这是怎么回事&#xff1f;ProcFS 更改Kallsyms 问题系统调用名称问题就这样…… 这是怎么回事&#xff1f; 早在…

如何把vue项目打包成桌面程序 electron-builder

引入 我们想要把我们写的vue项目,打包成桌面程序&#xff0c;我们需要使用electron-builder这个库 如何使用 首先添加打包工具 vue add electron-builder 选择最新版本 下载完毕 我们可以看到我们的package.json中多了几行 electron:build&#xff1a;打包我们的可执行程序 e…

vue实现二维数组表格渲染

在Vue中渲染二维数组表格可以采用嵌套的<template>和v-for指令。 写法一 <template> <table> <thead> <tr> <th v-for"(header, index) in headers" :key"index">{{ header }}</th> </tr> </t…

在 iOS 上安装自定企业级应用

了解如何安装您的组织创建的自定应用并为其建立信任。 本文适用于学校、企业或其他组织的系统管理员。 您的组织可以使用 Apple Developer Enterprise Program 创建和分发企业专用的 iOS 应用&#xff0c;以供内部使用。您必须先针对这些应用建立信任后&#xff0c;才能将其打…

服装品牌如何利用数字化工具提升商品管理效率

随着科技的快速发展&#xff0c;数字化工具在商品管理中的应用越来越广泛。数字化工具不仅可以提高商品管理的效率&#xff0c;还可以帮助企业更好地满足客户需求&#xff0c;提升市场竞争力。本文将探讨如何利用数字化工具提升商品管理效率。 一、建立数字化管理系统 数字化…

备战蓝桥杯---搜索(应用基础1)

话不多说&#xff0c;直接看题&#xff1a; 显然&#xff0c;我们直接用深搜&#xff0c;我们可以先把空位用结构体存&#xff0c;然后打表存小方块&#xff0c;再用数组存行列。 下面是AC代码&#xff1a; #include<bits/stdc.h> using namespace std; int a[12][12];…

【leetcode】1512. 好数对的数目(简单)题解学习

题目描述&#xff1a; 给你一个整数数组 nums 。 如果一组数字 (i,j) 满足 nums[i] nums[j] 且 i < j &#xff0c;就可以认为这是一组 好数对 。 返回好数对的数目。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3,1,1,3] 输出&#xff1a;4 解释&#xff1a;有 4 …

OSG程序如何适配在无显卡的Ubuntu系统中

最近&#xff0c;嵌入式机器需要搞一个使用OSG开发的程序&#xff0c;但是发现弄上去后&#xff0c;各种问题&#xff0c;非常头疼&#xff0c;所以我花费了很多时间去查阅资料&#xff0c;终于解决了这个问题&#xff0c;因此写一下博客&#xff0c;记录下这个问题&#xff0c…