算法思想之双指针

文章目录

    • 双指针
      • 字符串序列判定
      • 字符串所有整数最小和
      • 服务交换接口失败率分析
      • 分披萨
      • 最多团队

双指针

  • 双指针是指在解决问题时使用两个指针,通常分别指向数组或字符串中的不同位置,通过移动这两个指针来解决问题的一种技巧。双指针技巧常用于解决数组、链表或字符串相关的问题。
  • 双指针常见的应用题型包括:
    • 快慢指针:用于解决链表中的环检测、链表中间节点查找等问题。快慢指针可以帮助判断链表是否有环、找到链表的中间节点等。
    • 对撞指针:又称为双指针夹逼法,通常用于解决数组或字符串中的查找问题。例如在有序数组中查找两数之和、三数之和等问题。
    • 左右指针:使用两个指针分别从数组的两端开始向中间移动,用于解决数组或字符串中的问题,如判断是否存在某个目标值、查找满足条件的子数组等。
    • 滑动窗口:双指针技巧在滑动窗口算法中有广泛应用。滑动窗口是一种解决字符串或数组子串问题的技巧,通过维护一个窗口来解决问题。
    • 两数之和:给定一个数组和一个目标值,找到数组中的两个数使得它们的和等于目标值。双指针技巧可以用于解决这类问题。
  • 双指针技巧通常能够提高问题的解决效率,减少时间复杂度,并且可以解决一些复杂的数据处理问题。根据具体问题的要求和特点,选择合适的双指针技巧来解决问题会更加高效。

字符串序列判定

  • 题目描述

    输入两个字符串 S 和 L,都只包含英文小写字母。S 长度 <=100,L 长度 <=500,000。判定 S 是否是 L 的有效子串。

    判定规则:

    S 中的每个字符在 L 中都能找到(可以不连续),且 S 在L中字符的前后顺序与 S 中顺序要保持一致。

    (例如,S=”ace”是 L=”abcde”的一个子序列且有效字符是 a、c、e,而”aec”不是有效子序列,且有效字符只有 a、e)

    输入描述

    输入两个字符串 S 和 L,都只包含英文小写字母。S 长度<=100,L 长度<=500,000。先输入 S,再输入 L,每个字符串占一行。

    输出描述

    S 串最后一个有效字符在 L 中的位置。(首位从 0 开始计算,无有效字符返回 -1)

  • 示例1

    输入:
    ace
    abcde
    输出:4
    

    示例2

    输入:
    fgh
    abcde
    输出:-1
    
  • 题解:双指针

    1. 使用双指针 i 和 j,分别指向字符串 S 和 L 的开头。
    2. 遍历字符串L,对于 L 的每个字符:
      • 如果当前字符等于 S 的当前字符(即S[i] == L[j]),则移动 S 的指针 i,继续比较下一个字符
      • 如果当前字符不等于 S 的当前字符,继续遍历 L 下一个字符
    3. 如果 S 的指针 i 移动到了末尾(即 i == len(S)),则说明 S 是 L 的有效子串,输出当前 L 的指针位置 j
    4. 如果遍历完 L 后,仍然没有找到有效子串,则输出 -1
    import java.util.Scanner;
    public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {String S = sc.nextLine();String L = sc.nextLine();int sIndex = 0;int lastPos = -1;for (int i = 0; i < L.length(); i++) {if (sIndex == S.length()) {break;}if (S.charAt(sIndex) == L.charAt(i)) {lastPos = i;sIndex++;}}System.out.println(sIndex == S.length() ? lastPos : -1);}}
    }
    

字符串所有整数最小和

  • 题目描述

    输入字符串 s,输出 s 中包含所有整数的最小和。

    说明:

    字符串 s,只包含 a-z A-Z + -

    合法的整数包括

    • 正整数:一个或者多个0-9组成,如 0 2 3 002 102
    • 负整数:负号 – 开头,数字部分由一个或者多个0-9组成,如 -0 -012 -23 -00023

    输入要求

    包含数字的字符串

    输出要求

    所有整数的最小和

  • 用例1

    输入:bb1234aa
    输出:10
    

    用例2

    输入:bb12-34aa
    输出:-31
    说明:1+2+(-34) = -31
    
  • 题解1

    import java.util.Scanner;
    public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {String str = sc.nextLine();str += " "; // 处理字符串末尾为负数情况int sum = 0;int num = 0; // 数字前方为符号时拼接数字boolean flag = false; // 数字前方是否为负号char[] arr = str.toCharArray();for (int i = 0; i < arr.length; i++) {char c = arr[i];if (!Character.isDigit(c)) {if (flag) {sum -= num;num = 0;}flag = '-' == c;} else {if (flag) num = num * 10 + c - '0';else sum += c - '0';}}System.out.println(sum);}}
    }
    

    题解2:双指针

    从左到右扫描字符串,遇到数字时累加到结果中,遇到负号时将后面的负数减去。具体做法是使用两个指针 i 和 r,i 指向当前字符,r 指向负数的末尾。每次遇到负号时,将 r 移动到负数的末尾,将负数转换为整数后减去即可。

     import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {String str = sc.nextLine();int sum = 0;int r = 0;char[] arr = str.toCharArray();for (int i = 0; i < arr.length; i++) {char c = arr[i];if (Character.isDigit(c)) sum += c - '0';else if ('-' == c) {r = i + 1;while (r < arr.length && Character.isDigit(arr[r])) {r++; // 右指针指向负数后一个字符}sum -= i + 1 == r ? 0 : Integer.parseInt(str.substring(i + 1, r));i = r; // 计算完毕,移动左指针}}System.out.println(sum);}}}
    

服务交换接口失败率分析

  • 题目描述

    服务之间交换的接口成功率作为服务调用关键质量特性,某个时间段内的接口失败率使用一个数组表示,数组中每个元素都是单位时间内失败率数值,数组中的数值为 0 ~ 100 的整数,给定一个数值(minAverageLost)表示某个时间段内平均失败率容忍值,即平均失败率小于等于 minAverageLost,找出数组中最长时间段,如果未找到则直接返回 。

    输入要求

    输入有两行内容,

    第一行为 minAverageLost

    第二行为(数组),数组元素通过空格(“ “)分隔。

    minAverageLost 及数组中元素取值范围为 0−100 的整数,数组元素的个数不会超过 100 个

    输出要求

    找出平均值小于等于 minAverageLost 的最长时间段,输出数组下标对,格式 (beginindex) - (endindx)(下标从0开始),如果同时存在多个最长时间段,则输出多个下标对与下标对之间使用空格(” ”)拼接,多个下标对按下标对从小到大排序。

    如果不存在满足条件的时间段,则输出 NULL

  • 用例1

    输入:
    1
    0 1 2 3 4
    输出:0-2
    

    用例2

    输入:
    2
    0 0 100 2 2 99 0 2
    输出:0-1 3-4 6-7
    
  • 题解1

    import java.util.*;
    public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNextLine()) {int k = Integer.parseInt(sc.nextLine());String[] arr = sc.nextLine().split(" ");ArrayList<String> list = new ArrayList<>();int l = 0; int maxLen = 0; int sum = 0;for (int r = 0; r < arr.length; r++) {sum += Integer.parseInt(arr[r]);int len = r - l + 1; // 左右指针长度,指向同一个位置时长度为1if ((double) sum / len > k) {sum = 0; // 重置左右指针间的数值和l = r + 1; // 移动左指针指向下一个数字} else {if (len > maxLen) list.clear(); // 新的最大长度,清空小于该长度的时间段if (len >= maxLen) list.add(l + "-" + r);maxLen = Math.max(maxLen, len); // 更新最大长度}}if (list.isEmpty()) System.out.println("NULL");for (int i = 0; i < list.size(); i++) {if (i == list.size()-1) System.out.println(list.get(i));else System.out.print(list.get(i) + " ");}}}
    }
    

分披萨

  • 题目描述

    "吃货"和"馋嘴"两人到披萨店点了一份铁盘(圆形)披萨,并嘱咐店员将披萨按放射状切成大小相同的偶数个小块。但是粗心的服务员将披萨切成了每块都完全不同奇数块,且肉眼能分辨出大小。

    由于两人都想吃到最多的披萨,他们商量了一个他们认为公平的分法:从"吃货"开始,轮流取披萨。除了第一块披萨可以任意选取外,其他都必须从缺口选。

    他俩选披萨的思路不同。"馋嘴"每次都会选最大块的披萨,而且"吃货"知道"馋嘴"的想法。

    已知披萨小块的数量以及每块的大小,求"吃货"能分得的最大的披萨大小的总和。

    输入要求

    第 1 行为一个正整数奇数 N,表示披萨小块数量,其中 3 ≤ N < 500。接下来的第 2 行到第 N + 1 行(共 N 行),每行为一个正整数,表示第 i 块披萨的大小,其中 1 ≤ i ≤ N。

    披萨小块从某一块开始,按照一个方向次序顺序编号为 1 ∼ N,每块披萨的大小范围为 [1, 2147483647]

    输出要求

    "吃货"能分得到的最大的披萨大小的总和。

  • 用例1

    输入:
    5
    8
    2
    10
    5
    7
    输出:19
    说明:
    此例子中,有 5 块披萨。每块大小依次为 8、2、10、5、7。
    按照如下顺序拿披萨,可以使"吃货"拿到最多披萨:
    “吃货” 拿大小为 10 的披萨
    “馋嘴” 拿大小为 5 的披萨
    “吃货” 拿大小为 7 的披萨
    “馋嘴” 拿大小为 8 的披萨
    “吃货” 拿大小为 2 的披萨
    至此,披萨瓜分完毕,"吃货"拿到的披萨总大小为 10 +7 + 2 = 19
    可能存在多种拿法,以上只是其中一种。
    
  • 题解

    import java.util.*;
    public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {int n = sc.nextInt();ArrayList<Integer> list = new ArrayList<>();for (int i = 0; i < n; i++) {list.add(sc.nextInt());}Integer max = Collections.max(list); // 先拿最大的一块int maxIndex = list.indexOf(max);int ret = max, l = check(maxIndex - 1, n), r = check(maxIndex + 1, n);for (int i = 0; i < (n-1) / 2; i++) { // 除去最大一块后,轮流拿(n-1)/2次ret += Math.min(list.get(l), list.get(r));l = check(l - 1, n);r = check(r + 1, n);}System.out.println(ret);}}public static int check(int i, int n) {if (i < 0) return n - 1;else if (i > n - 1) return 0;else return i;}
    }
    

最多团队

  • 题目描述

    用数组代表每个人的能力,一个比赛活动要求参赛团队的最低能力值为 N,每个团队可以由 1 人或者 2 人组成,且 1 个人只能参加 1 个团队,计算出最多可以派出多少只符合要求的团队。

    输入要求

    第一行代表总人数,范围 1-500000

    第二行数组代表每个人的能力

    数组大小,范围 1-500000

    元素取值,范围 1-500000

    第三行数值为团队要求的最低能力值,范围 1-500000

    输出要求

    最多可以派出的团队数量

  • 用例1

    输入:
    5
    3 1 5 7 9
    8
    输出:3
    说明:说明 3、5组成一队 1、7一队 9自己一队 输出3
    

    用例2

    输入:
    7
    3 1 5 7 9 2 6
    8
    输出:4
    说明:3、5组成一队,1、7一队,9自己一队,2、6一队,输出4
    

    用例3

    输入:
    3
    1 1 9
    8
    输出:1
    说明:9自己一队,输出1
    
  • 题解1

    import java.util.*;
    public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {int n = sc.nextInt();int[] arr = new int[n];for (int i = 0; i < n; i++) arr[i] = sc.nextInt();int k = sc.nextInt();Arrays.sort(arr);int l = 0; int r = n - 1; int count = 0;while (r >= l) {if (arr[r] >= k) { // 单人参赛count++; r--;} else if (arr[l] + arr[r] >= k) {count++; l++; r--;} else if (arr[l] + arr[r] < k) {l++; // 能力太差,要么不参赛,要么跟可以单人参赛的人一起参赛}}System.out.println(count);}}
    }
    

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

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

相关文章

学透Spring Boot — 018. 优雅支持多种响应格式

这是我的专栏《学透Spring Boot》的第18篇文章&#xff0c;想要更系统的学习Spring Boot&#xff0c;请访问我的专栏&#xff1a;学透 Spring Boot_postnull咖啡的博客-CSDN博客。 目录 返回不同格式的响应 Spring Boot的内容协商 控制器不用任何修改 启动内容协商配置 访…

ngx_os_init

定义在 src\os\unix\ngx_posix_init.c ngx_int_t ngx_os_init(ngx_log_t *log) {ngx_time_t *tp;ngx_uint_t n; #if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)long size; #endif#if (NGX_HAVE_OS_SPECIFIC_INIT)if (ngx_os_specific_init(log) ! NGX_OK) {return NGX_ERR…

深信服护网蓝初面试题

《网安面试指南》https://mp.weixin.qq.com/s/RIVYDmxI9g_TgGrpbdDKtA?token1860256701&langzh_CN 5000篇网安资料库https://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247486065&idx2&snb30ade8200e842743339d428f414475e&chksmc0e4732df793fa3bf39…

游戏引擎学习第206天

回顾并为当天的工作定下目标 接着回顾了前一天的进展。之前我们做了一些调试功能&#xff0c;并且已经完成了一些基础的工作&#xff0c;但是还有一些功能需要继续完善。其中一个目标是能够展示实体数据&#xff0c;以便在开发游戏逻辑系统时&#xff0c;可以清晰地查看和检查…

HTML 表单:构建交互式网页的关键元素

HTML 表单:构建交互式网页的关键元素 引言 HTML表单是构建交互式网页的核心组件之一,它允许用户与网站进行交互,提交信息、填写问卷或进行其他操作。本文将深入探讨HTML表单的基础知识、常用元素、表单验证以及如何优化表单设计,以提高用户体验和网站的可访问性。 HTML表…

Qt音频采集:QAudioInput详解与示例

1. 简介 QAudioInput是Qt Multimedia模块中用于音频采集的核心类&#xff0c;能够从麦克风等输入设备实时获取原始音频数据&#xff08;PCM格式&#xff09;。本文将通过原理讲解和代码示例&#xff0c;帮助开发者快速掌握音频采集的核心技术。 2. 核心功能 支持多种音频格式&…

下载安装Node.js及其他环境

提示&#xff1a;从Node版本降级到Vue项目运行 文章目录 下载Node.js环境配置配置环境变量 安装 cnpm&#xff08;我需要安装&#xff09;安装脚手架安装依赖安装淘宝镜像&#xff08;注意会更新&#xff09;cnpm vs npm 与新旧版本核心差异包管理器不同功能差异如何选择&#…

【后端】ORM / ODM

长期不定期更新&#xff0c;建议关注收藏点赞。 概述 ORM&#xff08;Object-Relational Mapping&#xff0c;对象关系映射&#xff09;&#xff1a;面向关系型数据库&#xff0c;ORM将对象映射到数据库的表和行&#xff08;例如MySQL、PostgreSQL&#xff09;。ODM&#xff0…

无限滚动(Infinite Scroll)页面谷歌不收录!必须改回分页吗?

近三年&#xff0c;全球超过58%的网站采用无限滚动设计&#xff08;数据来源&#xff1a;PageTraffic 2023&#xff09; 谷歌官方数据显示&#xff0c;动态加载内容的索引失败率高达73%&#xff08;Google Webmaster Report 2022&#xff09;&#xff0c;而采用纯无限滚动的页…

手写JSX实现虚拟DOM

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…

网络性能优化参数关系解读 | TCP Nagle / TCP_NODELAY / TCP_QUICKACK / TCP_CORK

注&#xff1a;本文为 “网路性能优化” 相关文章合辑。 未整理去重。 如有内容异常&#xff0c;请看原文。 TCP_NODELAY 详解 lenky0401 发表于 2012-08-25 16:40 在网络拥塞控制领域&#xff0c;Nagle 算法&#xff08;Nagle algorithm&#xff09;是一个非常著名的算法&…

玄机-应急响应-webshell查杀

题目要求&#xff1a; 要求获取四个flag webshell查杀&#xff1a; 常见的webshell&#xff1a; PHP: eval(), system(), exec(), shell_exec(), passthru(), assert(), base64_decode() ASP: Execute(), Eval(), CreateObject() JSP: Runtime.getRuntime().exec() websh…

docker存储卷及dockers容器源码部署httpd

1. COW机制 Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层。 如果运行中的容器修改了现有的一个已经存在的文件,那么该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本依然存在,只是已经被读写层中该文件…

PyTorch中卷积层torch.nn.Conv2d

在 PyTorch 中&#xff0c;卷积层主要由 torch.nn.Conv1d、torch.nn.Conv2d 和 torch.nn.Conv3d 实现&#xff0c;分别对应一维、二维和三维卷积操作。以下是详细说明&#xff1a; 1. 二维卷积 (Conv2d) - 最常用 import torch.nn as nn# 基本参数 conv nn.Conv2d(in_channe…

从 ZStack 获取物理机与云主机信息并导出 Excel 文件

文章目录 从 ZStack 获取物理机与云主机信息并导出 Excel 文件环境zstack 官网客户端封装讲解 获取物理机信息讲解 获取云主机信息并关联物理机讲解 导出数据到 Excel 文件讲解 运行主程序讲解 总结最终文档效果完整代码 从 ZStack 获取物理机与云主机信息并导出 Excel 文件 在…

5.好事多磨 -- TCP网络连接Ⅱ

前言 第4章节通过回声服务示例讲解了TCP服务器端/客户端的实现方法。但这仅是从编程角度的学习&#xff0c;我们尚未详细讨论TCP的工作原理。因此&#xff0c;将详细讲解TCP中必要的理论知识&#xff0c;还将给出第4章节客户端问题的解决方案。 一、回声客户端完美实现 第4章…

sql server数据库可疑修复

sql server数据库可疑修复 从上图可以看到数据库nchrdb显示可疑&#xff0c;导致原因为NC系统在增加公共薪资项目的时候&#xff0c;扩展字段报错了&#xff0c;第一次遇到这种情况&#xff0c;折腾了很久终于解决&#xff0c;记下解决方案&#xff1a; 1&#xff0c;将SQL数据…

Flutter之页面布局二

目录&#xff1a; 1、列表布局1.1、基础列表1.2、水平滑动的列表1.3、网格列表1.3、不同列表项的列表1.4、包含间隔的列表1.6、长列表 2、滚动2.1、浮动的顶栏2.2、平衡错位滚动 1、列表布局 1.1、基础列表 import package:flutter/material.dart;void main() > runApp(con…

ARM------硬件程序开发

硬件程序开发流程 相关硬件的工作原理 理解硬件的工作原理&#xff0c;明确硬件的功能和用途。 硬件连接 将硬件设备正确连接到开发板上。 编写程序 根据硬件功能编写相应的程序代码。 调试验证 通过调试工具验证程序的正确性&#xff0c;确保硬件功能正常。 控制LED的…

《QT从基础到进阶·七十四》Qt+C++开发一个python编译器,能够编写,运行python程序改进版

1、概述 源码放在文章末尾 根据上一篇文章回顾下利用QtC实现了一个简易的python编译器&#xff0c;类似pycharm或vsCode这样的编译器&#xff0c;该python编译器目前实现了如下功能&#xff1a; &#xff08;1&#xff09;支持编写python程序 &#xff08;2&#xff09;编写代…