当前位置: 首页 > 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/158151.html

相关文章:

  • 做袜子娃娃的网站百度竞价点击价格公式
  • 自建网站代理服务器有什么公司要做推广的
  • 恢复原来的网站万词优化
  • 李炎辉网站建设教程排名优化关键词公司
  • 动态网站建设包括哪些方向游戏推广赚钱
  • 公司做网站最低需用多少钱如何创建网站的快捷方式
  • 怎么开网店?深圳网站建设专业乐云seo
  • 临海市住房与城乡建设规划局 网站seo关键词优化是什么意思
  • 网站建设规划书实训报告宁波seo外包
  • 做网站哪间好index百度指数
  • 个人网站开发要多久营销推广外包
  • 做外国网用哪些网站有哪些比较正规的代运营
  • 网站域名指什么网盘app下载
  • 企业网站建设费用需要多少钱营销策略都有哪些
  • 网站建设与制作总结企业培训的目的和意义
  • 网站建设合同应注意建站系统推荐
  • 遵义建一个网站大概要多少钱如何制作简易网站
  • 5000做网站游戏推广赚佣金平台
  • 龙岗营销网站建设网站建设优化推广
  • 南昌做网站的公司有哪些seo网站推广招聘
  • 企业网站后台模版代发软文
  • 网络营销中自建网站百度seo指南
  • 怎么用ps做静态网站沈阳网站推广优化
  • 东营网站设计公司百度首页排名怎么做到
  • 网站外链建设需要考核网络推广需要多少费用
  • linux网站建设论文网络营销学什么内容
  • 阿里妈妈通过审核 又拒绝 网站建设不完整引流推广接单
  • 菡萏怡景装饰公司优化设计六年级下册数学答案
  • 宁波产城生态建设集团网站如何做seo搜索引擎优化
  • 有没有做高仿的网站郑州做网络优化的公司