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

做一个答疑网站西安网站优化培训

做一个答疑网站,西安网站优化培训,哪些网站做家政推广,网站维护工程师薪酬双指针篇 在 Java 中,双指针(Two Pointers)是一种常见的算法技巧,通常用于解决数组、链表或字符串相关的问题。它通过使用两个指针(索引或引用)来遍历数据结构,以减少时间复杂度或空间复杂度。…

双指针篇

在 Java 中,双指针(Two Pointers)是一种常见的算法技巧,通常用于解决数组、链表或字符串相关的问题。它通过使用两个指针(索引或引用)来遍历数据结构,以减少时间复杂度或空间复杂度。根据问题的类型和指针的移动方式,双指针可以分为以下几种分类。


双指针类型讲解

1. 对撞指针(Two Pointers Moving Towards Each Other)

  • 描述: 两个指针分别从数组的两端向中间移动,直到满足某个条件或相遇。
  • 适用场景: 常用于有序数组的查找问题(如两数之和)、反转问题或分区问题。
  • 时间复杂度: 通常为 O(n)。
  • 例子: 两数之和(Two Sum,假设数组已排序)。
示例代码
public class TwoSum {public static int[] twoSum(int[] nums, int target) {int left = 0;int right = nums.length - 1;while (left < right) {int sum = nums[left] + nums[right];if (sum == target) {return new int[]{left, right};} else if (sum < target) {left++;} else {right--;}}return new int[]{-1, -1}; // 未找到}public static void main(String[] args) {int[] nums = {2, 7, 11, 15};int target = 9;int[] result = twoSum(nums, target);System.out.println("[" + result[0] + ", " + result[1] + "]"); // 输出 [0, 1]}
}

2. 快慢指针(Fast and Slow Pointers)

  • 描述: 一个指针(快指针)移动速度快,另一个指针(慢指针)移动速度慢,通常快指针每次走两步,慢指针每次走一步。
  • 适用场景: 常用于链表问题(如检测环、找中间节点)或数组中的循环检测。
  • 时间复杂度: 通常为 O(n)。
  • 例子: 检测链表中是否有环(LeetCode 141)。
示例代码
class ListNode {int val;ListNode next;ListNode(int val) {this.val = val;}
}public class LinkedListCycle {public boolean hasCycle(ListNode head) {if (head == null || head.next == null) return false;ListNode slow = head;ListNode fast = head;while (fast != null && fast.next != null) {slow = slow.next;         // 慢指针走一步fast = fast.next.next;    // 快指针走两步if (slow == fast) {       // 相遇说明有环return true;}}return false;}
}

3. 同向指针(Two Pointers Moving in the Same Direction)

  • 描述: 两个指针从同一端开始,向同一方向移动,通常一个指针用于遍历,另一个指针用于标记或记录。
  • 适用场景: 常用于滑动窗口问题、子数组问题或字符串匹配。
  • 时间复杂度: 通常为 O(n)。
  • 例子: 找到最小的子数组和(LeetCode 209)。
示例代码
public class MinSubArrayLen {public static int minSubArrayLen(int target, int[] nums) {int left = 0;int sum = 0;int minLen = Integer.MAX_VALUE;for (int right = 0; right < nums.length; right++) {sum += nums[right];while (sum >= target) {minLen = Math.min(minLen, right - left + 1);sum -= nums[left];left++;}}return minLen == Integer.MAX_VALUE ? 0 : minLen;}public static void main(String[] args) {int[] nums = {2, 3, 1, 2, 4, 3};int target = 7;System.out.println(minSubArrayLen(target, nums)); // 输出 2}
}

4. 固定距离指针(Fixed Distance Pointers)

  • 描述: 两个指针之间的距离固定,通过移动这两个指针来解决问题。
  • 适用场景: 常用于字符串匹配、定长子数组问题。
  • 时间复杂度: 通常为 O(n)。
  • 例子: 检查字符串中是否有重复字符的最长子串(固定窗口大小)。
示例代码
public class CheckDuplicates {public static boolean checkDuplicates(String s, int k) {int[] count = new int[26];for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);count[c - 'a']++;if (i >= k) {count[s.charAt(i - k) - 'a']--;}if (count[c - 'a'] > 1) {return true; // 发现重复字符}}return false;}public static void main(String[] args) {String s = "abcba";int k = 3;System.out.println(checkDuplicates(s, k)); // 输出 true}
}

总结

类型指针移动方式典型问题
对撞指针从两端向中间移动两数之和、反转数组
快慢指针一个快一个慢链表环检测、中间节点
同向指针同方向不同速滑动窗口、子数组问题
固定距离指针保持固定间距移动定长子串、重复字符检测

双指针的核心在于通过巧妙地移动指针来避免嵌套循环,从而优化算法效率。

二、例题演示

1. 美丽的区间

题目描述

给定一个长度为 nn 的序列 a1,a2,⋯,ana1,a2,⋯,a**n 和一个常数 SS

对于一个连续区间如果它的区间和大于或等于 SS,则称它为美丽的区间。

对于一个美丽的区间,如果其区间长度越短,它就越美丽。

请你从序列中找出最美丽的区间。

输入描述

第一行包含两个整数 n,Sn,S,其含义如题所述。

接下来一行包含 nn 个整数,分别表示 a1,a2,⋯,ana1,a2,⋯,a**n

10≤N≤10510≤N≤105,1×ai≤1041×a**i≤104,1≤S≤1081≤S≤108。

输出描述

输出共一行,包含一个整数,表示最美丽的区间的长度。

若不存在任何美丽的区间,则输出 00。

输入输出样例

示例 1

输入

5 6
1 2 3 4 5

输出

2

解题思路:

  • 本题双指针的类型属于快慢指针,通过low、high两个指针,实现检索最小数对,通过两个while循环,减少了算法复杂度。
  • 本题不可以用排序,排序会导致数组顺序变化,因为前后数字关系他们的和。笔者也是一开始混进了排序的思路漩涡,倒是卡住了。

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改public class 蓝桥杯真题_美丽的区间 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();int s = scan.nextInt();int[] a = new int[n];for (int i=0;i<n;i++) {a[i] = scan.nextInt();}int low = 0;int high = 0;int res = n;int sum = 0;while (high < n) {sum = sum + a[high];while(sum>=s) {res = Math.min(res,high-low+1);sum = sum -a[low];low++;}high++;}if(res == n) {System.out.println(0);}else {System.out.println(res);}scan.close();}
}

2.聪明的小羊肖恩

问题描述

小羊肖恩是一只非常聪明的绵羊,在牧场里与其他绵羊一起生活。有一天,它在草地上漫步时,发现了一些数字。它猜想这些数字可能在某些方面有用,于是把它们带回了牧场,并开始研究它们。

具体来说,小羊有一个长度为 nn 的数组,第 ii 个数字的值为 aia**i。小羊肖恩心中想了两个数 LL 和 RR,它想知道有多少对下标对 (i,j)(i,j) 满足以下条件:

  • 1≤i<j≤n1≤i<jn
  • L≤ai+aj≤RLa**i+a**jR

请你帮它找出满足条件的下标对数量。

输入格式

第一行输入三个整数 nn,LL 和 RR

第二行输入 nn 个整数 a1,a2,a3,…,ana1,a2,a3,…,a**n,表示数组 aa

数据范围保证:1≤n≤2×1051≤n≤2×105,1≤ai≤1091≤a**i≤109,1≤L≤R≤1091≤LR≤109。

输出格式

输出一个整数,表示满足条件的下标对数量。

样例输入

3 2 4
1 2 3

样例输出

2

说明

样例中满足条件的下标对有 (1,2)(1,2) 和 (1,3)(1,3)。

思路解答
  • 本题类型即是相撞指针类型,通过找到两个点的区间,求出答案。
import java.util.Scanner;
import java.util.Arrays;
// 1:无需package
// 2: 类名必须Main, 不可修改public class 蓝桥杯真题_聪明的小羊肖恩 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);long n = scan.nextLong();long l = scan.nextLong();long r = scan.nextLong();long res = 0;long[] a = new long[(int)n];for (long i=0;i<n;i++) {a[(int)i] = scan.nextInt();}Arrays.sort(a);//先排序,完成数组的单调性for(long i=0;i<n;i++) {long j = n-1; //j做右指针while(j>i&&a[(int)j]+a[(int)i]>r) {j--;//先找一边}long k = i+1;while (k<=j&&a[(int)i]+a[(int)k]<l) {k=k+1;}res = res +Math.max(0,j-k+1);}System.out.print(res);scan.close();}
}
3.连续子序列的个数

问题描述

给你一个长度为 nn 的数组 aa 和一个数字 mm ,请你计算这个数组有多少个连续子序列的和大于等于 mm

如果两个连续子序列来自数组中的不同位置,我们认为它们是不同的,即使它们在内容上是相同的。

输入格式

第一行输入两个整数表示 nn 和 mm

第二行输出 nn 个整数表示 aa 数组的元素。

输出格式

输出一个整数表示 aa 数组有多少个连续子序列的和大于等于 mm

样例输入

4 10
6 1 2 7

样例输出

2
思路解答
  • 本题类型即是滑动窗口类型,通过找到两个点的区间,求出答案。
import java.util.Scanner;public class 蓝桥杯真题_连续子序列的个数 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 读取 n 和 m 的值long n = scanner.nextLong();long m = scanner.nextLong();// 创建长度为 n 的数组来存储输入的元素long[] a = new long[(int) n];for (int i = 0; i < n; i++) {a[i] = scanner.nextLong();}// 初始化左右指针、当前子数组的和以及满足条件的子数组数量long left = 0;long right = 0;long sum = 0;long cnt = 0;// 使用滑动窗口来遍历数组while (right < n) {// 累加当前元素到总和sum += a[(int) right];// 当总和大于等于 m 时,更新满足条件的子数组数量并调整左指针while (sum >= m) {cnt += (n - right);sum -= a[(int) left];left++;}// 右指针右移right++;}// 输出满足条件的子数组数量System.out.println(cnt);scanner.close();}
}

双指针的核心在于通过巧妙地移动指针来避免嵌套循环,从而优化算法效率。希望这些分类和例子能帮到你!😁

http://www.dtcms.com/wzjs/110180.html

相关文章:

  • 深圳返利网站开发网络推广主要是做什么工作
  • 三端互通传奇手游找服网站谷歌官方网站首页
  • 做个营销型网站深圳网络营销策划公司
  • 南通做网站推广的公司大数据营销名词解释
  • 做网站快速排名培训学校招生方案
  • 做网站的软件是哪个互联网营销师题库
  • 个人网站推广app如何推广自己的店铺?
  • html5 音乐网站网址关键词查询网站
  • 有域名如何做网站百度浏览器下载官方免费
  • 广西商城网站建设黄冈黄页88网黄冈房产估价
  • 柳州网站建设新手怎么引流推广推广引流
  • 网站建设 网站软文推广chatgpt 链接
  • 安丘网站建设开发常用的网络营销方法
  • 北京网吧百家号seo怎么做
  • 怎样备份网站app拉新推广平台
  • 天津网站建设业务网站互联网推广
  • 国外的智慧城市建设网站百度小说网
  • 汽车精品设计网站建设如何注册一个自己的网站
  • 下wordpress台州seo
  • 大学生电子商务专业网站设计南昌seo方案
  • 玩具电子商务网站建设论文深圳纯手工seo
  • 物联网是什么意思推广seo网站
  • 集成wamp访问域名打开tp做的网站东莞关键词排名seo
  • 简述对网站进行评析的几个方面.培训学校管理系统
  • 黑龙江省住房和建设厅网站保定seo推广公司
  • 十大那种直播软件seo网络优化专员是什么意思
  • 东莞外贸建站及推广电商的推广方式有哪些
  • 宁波网站推广平台咨询网络营销推广专家
  • 怎么在网站上做按钮百度爱采购推广怎么入驻
  • 怎么建个人公司网站怎么自己创建网站