尺取法
尺取法又叫双指针(two pointers)是竞赛中常用的优化基技巧,用来解决区间问题,操作简单。如果是单调区间也常用二分法
需要操作两个变量,可以用两个下标(指针)i,j 扫描区间。有二重循环,复杂度为O(n2)
for(int i=0;i<n;i++) for(int j=n-1;j>=0;j--) { }
实际上尺取法就是把二重循环变为一个循环,在这个循环中同时处理i,j,时间复杂都也从O(n2)变为O(n)
int i=0; int j=n-1; while(i<j) { .....i++; .....j--; } //用for实现 for(int i=0;j=n-1;i<j;i--;j++) { }
在扫描方式中有两种扫描方式
(1)反向扫描:i和j反向相同,i从头到尾,j从尾到头。在中将相会。
(2)同向扫描。又称快慢指针。都是从头到尾,速度不同。
反向扫描经典例题:
输入n个整数放在a[]中,找出其中两个数,他们之和等于整数m所有整数都是int类型
输入样例
9
21 4 5 6 13 65 32 9 23
28
输出
5 23
import java.sql.Array; //import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; public class Main{ public static void main(String[]args) { Scanner input=new Scanner(System.in); int n= input.nextInt();
int []ant=new int[n]; for(int i=0;i< ant.length;i++) { ant[i]= input.nextInt(); } int m= input.nextInt(); Arrays.sort(ant); int i=0;int j=n-1; while(i<j) { int sum=ant[i]+ant[j]; if(sum>m) { j--; } else if (sum<m) { i++; } else { System.out.println(ant[i]+" "+ant[j]); i++; } } } }
2 判断回文串
给定一个字符判定它是否是回文串
输入第一行输入一个整数n表示,表示测试实例个数。后面输入n个字符串
是回文输出yes,不是输出no
常规做法:
import java.util.ArrayList; import java.util.Scanner; public class Main{ public static void main(String[]args) { ArrayList<String> list=new ArrayList<>(); Scanner input=new Scanner(System.in); int n= input.nextInt(); while(n-->0) { String p= input.next(); if(check(p)) { list.add("yes"); } else{ list.add("no"); } } for(int i=0;i< list.size();i++) { System.out.println(list.get(i)); } } public static boolean check(String m) { StringBuilder st=new StringBuilder(m); st.reverse(); int count=0; for(int i=0;i< st.length();i++) { if(st.charAt(i)!=m.charAt(i)) { return false; } else{ count++; } } if(count==m.length()) { return true; } else{ return false; } } }
用尺取法判断回文串,采用双指针的算法
import java.util.ArrayList; import java.util.Scanner; public class Main { public static void main(String[]args) { Scanner input=new Scanner(System.in); ArrayList<String> list=new ArrayList<>(); int n= input.nextInt(); while(n-->0) { boolean key=true; String s= input.next(); int i=0; int j=s.length()-1; while(i<j) { if(s.charAt(i)!=s.charAt(j)) { key=false; break; } i++; j--; } if(key) { list.add("YES"); } else{ list.add("NO"); } } for(int i=0;i< list.size();i++) { System.out.println(list.get(i)); } } }
寻找区间和,给定一个数组,在数组中找到一个区间,使得这个区间和等于S 输出起点和终点的位置
package Main6; import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner input = new Scanner(System.in); int n = input.nextInt(); int[] ant = new int[n]; for (int i = 0; i < n; i++) { ant[i] = input.nextInt(); } int s = input.nextInt(); int i = 0; int j = 0; int sum = ant[0]; while (j < n) { if (sum >= s){ if(sum==s) System.out.println(i+" "+j); sum-=ant[i]; i++; if(i>j&&i<ant.length) {sum=ant[i];j++;} } if(sum<s) {j++; if(j<ant.length)sum+=ant[j];} } } }
找相同数对,给定一串数,以及一个数字C要求计算A-B=C的数对的个数
import java.util.Arrays; import java.util.Scanner; public class Main{ public static void main(String[]args) { Scanner input=new Scanner(System.in); int n= input.nextInt(); int c= input.nextInt(); int []ant=new int[n+1]; for(int i=1;i<=n;i++) { ant[i]= input.nextInt(); } Arrays.sort(ant); long ans=0; for(int i=1,j=1,k=1;i<=n;i++) { while(j<=n&&ant[j]-ant[i]<c) { j++; } while(k<=n&&ant[k]-ant[i]<=c) { k++; } if(k-1>=1&&j<=n&&i<=n&&ant[j]-ant[i]==c&&ant[k-1]-ant[i]==c) { ans+=k-j; } } System.out.println(ans); } }
用尺取法进行数组去重复
import java.util.Arrays; public class ArrayDeduplication { public static int[] removeDuplicates(int[] nums) { // 首先,判断数组是否为空或长度为0,如果是,则返回原数组 if (nums == null || nums.length == 0) { return nums; } // 数组长度为1时也无需去重,直接返回原数组 if (nums.length == 1) { return nums; } // 初始化双指针 int left = 0; // 左指针用于记录不重复元素的位置 int right = 1; // 右指针用于遍历数组 // 开始尺取法去重 while (right < nums.length) { // 如果当前右指针指向的元素与左指针指向的元素不相等 // 则说明找到一个新的不重复元素 if (nums[right] != nums[left]) { // 将不重复元素放到左指针的下一个位置 nums[++left] = nums[right]; } // 右指针继续向右移动 right++; } // 返回去重后的数组,长度为left+1 return Arrays.copyOf(nums, left + 1); } public static void main(String[] args) { int[] nums = {1, 1, 2, 2, 3, 4, 4, 5, 6, 6}; int[] result = removeDuplicates(nums); System.out.println("去重后的数组为:"); for (int num : result) { System.out.print(num + " "); } } }
本文来自博客园,作者:LILi2209,转载请注明原文链接:https://www.cnblogs.com/Lili-202209/p/17357727.html

浙公网安备 33010602011771号