双指针-合并两个有序的数组
双指针-判断是否是回文字符串
双指针-合并区间
双指针-最小覆盖子串
双指针-反转字符串
双指针-最长无重复子数组
双指针-盛水最多的容器
双指针-接雨水问题
描述:给出一个有序的整数数组 A 和有序的整数数组 B ,请将数组 B 合并到数组 A 中,变成一个有序的升序数组
数据范围: 0≤n,m≤100,∣Ai∣<=100,∣Bi∣<=100
注意:
1.保证 A 数组有足够的空间存放 B 数组的元素, A 和 B 中初始的元素数目分别为 m 和 n,A的数组空间大小为 m+n
2.不要返回合并的数组,将数组 B 的数据合并到 A 里面就好了,且后台会自动将合并后的数组 A 的内容打印出来,所以也不需要自己打印
3.A 数组在[0,m-1]的范围也是有序的
输入:
[1,2,3],[2,5,6]
返回值:
[1,2,2,3,5,6]
import java.util.*;
public class Solution {
public void merge(int A[], int m, int B[], int n) {
int[] res = new int[m+n];
int i=0,j=0,r=0;
while(iB,B先放
res[r++] = B[j++];
}
}
//如果A,B其中有一个遍历完,另一个没遍历完,则将未遍历完的数组中的元素全部加入res中
while(i
描述:给定一个长度为 n 的字符串,请编写一个函数判断该字符串是否回文。如果是回文请返回true,否则返回false。
字符串回文指该字符串正序与其逆序逐字符一致。
数据范围:0
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param str string字符串 待判断的字符串
* @return bool布尔型
*/
public boolean judge (String str) {
// write code here
// 判断特殊情况
if (str == null || str.length() == 0) {
return false;
}
// 定义双指针,不相同则不是回文串
for (int i = 0, j = str.length()-1; i < j; i++, j--){
if (str.charAt(i) != str.charAt(j)) return false;
}
return true;
}
}
描述:
给出一组区间,请合并所有重叠的区间。
请保证合并后的区间按区间起点升序排列。
数据范围:区间组数 0≤n≤2×10^5,区间内 的值都满足 0≤val≤2×10^5
要求:空间复杂度 O(n)O(n),时间复杂度 O(nlogn)O(nlogn)
进阶:空间复杂度 O(val)O(val),时间复杂度O(val)O(val)
import java.util.*;
/**
* Definition for an interval.
* public class Interval {
* int start;
* int end;
* Interval() { start = 0; end = 0; }
* Interval(int s, int e) { start = s; end = e; }
* }
*/
public class Solution {
public ArrayList merge(ArrayList intervals) {
ArrayList res = new ArrayList<>();
//去除特殊情况
if(intervals.size() == 0){
return res;
}
Collections.sort(intervals, new Comparator(){
public int compare(Interval o1, Interval o2){
if(o1.start != o2.start)
return o1.start - o2.start;
else
return o1.end - o2.end;
}
});
//放入第一个区间
res.add(intervals.get(0));
int count = 0;
//遍历后续区间,查看是否与末尾有重叠
for(int i = 1; i < intervals.size(); i++){
Interval o1 = intervals.get(i);
Interval origin = res.get(count);
if(o1.start > origin.end){
res.add(o1);
count++;
//区间有重叠,更新结尾
}else{
res.remove(count);
Interval s = new Interval(origin.start, o1.end);
if(o1.end < origin.end)
s.end = origin.end;
res.add(s);
}
}
return res;
}
}
描述:
给出两个字符串 s 和 t,要求在 s 中找出最短的包含 t 中所有字符的连续子串。
数据范围:0≤∣S∣,∣T∣≤10000,保证s和t字符串中仅包含大小写英文字母
例如:
S ="XDOYEZODEYXNZ"S=“XDOYEZODEYXNZ”
T =“XYZ"T=“XYZ”
找出的最短子串为"YXNZ”“YXNZ”.
注意:
如果 s 中没有包含 t 中所有字符的子串,返回空字符串 “”;
满足条件的子串可能有很多,但是题目保证满足条件的最短的子串唯一。
输入:
“XDOYEZODEYXNZ”,“XYZ”
返回值:
“YXNZ”
import java.util.*;
public class Solution {
/**
*
* @param S string字符串
* @param T string字符串
* @return string字符串
*/
public String minWindow (String S, String T) {
// 定义边界排序特殊情况
if(S.length() == 0 || T.length() == 0) {
return "" ;
}
// hash初始化
int minCount = Integer.MAX_VALUE ;
int[] hash = new int[128] ;
for(int i = 0 ; i < T.length() ; i ++) {
hash[T.charAt(i)] -- ;
}
int minLen = Integer.MAX_VALUE ;//记录最小覆盖子串的长度
int ri = 0 ;//记录最小覆盖子串的左边界
int rj = 0 ;//记录最小覆盖子串的右边界
int f = 0 ;//窗口右边界
int s = 0 ;//窗口左边界
while(f < S.length()) {//右边界向右移动
hash[S.charAt(f)]++ ;//将当前右边界坐对对应的字符加入hash
while(s <= f && check(hash)) {//如果已经覆盖了,则不断让左边界右移,寻找最短的满足要求的子串
if(f - s + 1 < minLen) {//更新小覆盖子串的记录
minLen = f - s + 1 ;
ri = s ;
rj = f ;
}
hash[S.charAt(s)] -- ;//将左边界移除hash
s ++ ;//左边界右移
}
f ++ ;//右边界右移
}
if(f - s + 1 > S.length()) {//如果右边界超出S时左边界都没动过,说明不存在覆盖子串
return "" ;
} else {//截取
return S.substring(ri , rj + 1) ;
}
}
//检查是否有小于0的
boolean check(int[] hash) {
for (int i = 0; i < hash.length; i++) {
if (hash[i] < 0)
return false;
}
return true;
};
}
描述:
写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)
数据范围: 0≤n≤1000
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
输入:
“abcd”
返回值:
“dcba”
import java.util.*;
public class Solution {
/**
* 反转字符串
* @param str string字符串
* @return string字符串
*/
public String solve (String str) {
// write code here
char[] ans = str.toCharArray();
int len = str.length();
for(int i = 0 ; i < len ;i++){
ans[i] = str.charAt(len-1-i);
}
return new String(ans);
}
}
描述:
给定一个长度为n的数组arr,返回arr的最长无重复元素子数组的长度,无重复指的是所有数字都不相同。
子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组
输入:
[1,2,3,1,2,3,2,2]
返回值:
3
说明:
最长子数组为[1,2,3]
import java.util.*;
public class Solution {
/**
*
* @param arr int整型一维数组 the array
* @return int整型
*/
public int maxLength (int[] arr) {
// write code here
if (arr.length == 0){
return 0;
}
HashMap map = new HashMap<>();
int max = 0;
for (int i = 0, j = 0; i < arr.length; ++i) {
if (map.containsKey(arr[i])) {
j = Math.max(j, map.get(arr[i]) + 1);
}
map.put(arr[i], i);
max = Math.max(max, i - j + 1);
}
return max;
}
}
import java.util.*;
public class Solution {
/**
*
* @param arr int整型一维数组 the array
* @return int整型
*/
public int maxLength (int[] arr) {
//用链表实现队列,队列是先进先出的
Queue queue = new LinkedList<>();
int res = 0;
for (int c : arr) {
while (queue.contains(c)) {
//如果有重复的,队头出队
queue.poll();
}
//添加到队尾
queue.add(c);
res = Math.max(res, queue.size());
}
return res;
}
}
import java.util.*;
public class Solution {
/**
*
* @param arr int整型一维数组 the array
* @return int整型
*/
public int maxLength (int[] arr) {
int left = 0, right = 0, max = 0;
Set set = new HashSet<>();
while (right < arr.length) {
// 有重复的,直接删除前面的数字
if (set.contains(arr[right])) {
set.remove(arr[left++]);
} else {
set.add(arr[right++]);
max = Math.max(max, set.size());
}
}
return max;
}
}
描述:
给定一个数组height,长度为n,每个数代表坐标轴中的一个点的高度,height[i]是在第i点的高度,请问,从中选2个高度与x轴组成的容器最多能容纳多少水
1.你不能倾斜容器
2.当n小于2时,视为不能形成容器,请返回0
3.数据保证能容纳最多的水不会超过整形范围,即不会超过2^31-1
数据范围:
0<=height.length<=10^5
0<=height[i]<=10^4
输入:
[1,7,3,2,4,5,8,2,7]
返回值:
49
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param height int整型一维数组
* @return int整型
*/
public int maxArea (int[] height) {
int i = 0, j = height.length - 1;
int h = 1, max = 0;
while (i < j) {
if (height[i] < h) { // 左板不达标
i++;
} else if (height[j] < h) { // 右板不达标
j--;
} else {
max = Math.max(h++ * (j - i), max); // 记录水高度为h时的最大盛水量
}
}
return max;
}
}
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param height int整型一维数组
* @return int整型
*/
public int maxArea (int[] height) {
// write code here
int left =0,right = height.length-1;
int max = 0;
while(left
描述:
给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个柱子高度图,计算按此排列的柱子,下雨之后能接多少雨水。(数组以外的区域高度视为0)
数据范围:数组长度 0≤n≤2×10^5,数组中每个值满足 0 要求:时间复杂度 O(n)O(n)import java.util.*;
public class Solution {
/**
* max water
* @param arr int整型一维数组 the array
* @return long长整型
*/
public long maxWater (int[] arr) {
//排除空数组
if(arr.length == 0)
return 0;
long res = 0;
//左右双指针
int left = 0;
int right = arr.length - 1;
//中间区域的边界高度
int maxL = 0;
int maxR = 0;
//直到左右指针相遇
while(left < right){
//每次维护往中间的最大边界
maxL = Math.max(maxL, arr[left]);
maxR = Math.max(maxR, arr[right]);
//较短的边界确定该格子的水量
if(maxR > maxL)
res += maxL - arr[left++];
else
res += maxR - arr[right--];
}
return res;
}
}