第一题:452. 用最少数量的箭引爆气球
- 题目说明
- 求解思路
1)就是具有相同区域的球,可以一次性打掉。问题就是如何判别球之前有区域的重叠。 - . 求解步骤
1)首先对数据进行排序,第一个字母从小到大排列。
2)寻找到最小右边界,如果后面一个求的位置在最小右边界的左边,那么可以视为这个球能够同上一个球一起打掉,并且更新新的最小右边界;
3)如果没有落在最小右边界的左边,那么就需要一个新的箭,同时更新最小右边界。
4)最后输出需要多少支箭。 - 代码展示
class Solution {
public int findMinArrowShots(int[][] points) {
//使用贪心算法:设置一个重叠气球的最小右边界,如果需要添加新的箭,一定要大于这个边界
//1)先进行排序,按照第一个数字大小进行从小到大排序
Arrays.sort(points,(a,b) ->{
return a[0]<b[0]?-1:1; // ab代表前后的两个数
});
System.out.println(Arrays.deepToString(points)); //易错点:多维数组的输出
//2)循环开始
int num=1;
int rightBor=points[0][1];
for(int i=1;i<points.length;i++){
if(points[i][0]>rightBor){
num++;
rightBor=points[i][1];
}else{
rightBor=points[i][1]>rightBor?rightBor:points[i][1];
}
}
return num;
}
}
- 补充说明
1)数组进行排序的改写:
如果是单维数组,那么需要用包装类装(其实是一个匿名内部类Comportor,写成了lambda表达式)
如果是多维数组,那么不一定需要是包装类的数据类型。
//1)一维数组:逆序排列(重写sort方法)
Integer[] data=new Integer[]{3,2,5,3,6,2,6,1};
Arrays.sort(data,( a, b)-> b-a );
System.out.println("排序好的数组="+Arrays.toString(data));
//2)二维数组排序(重写sort方法)
//先按第一个数的正序排,如果相同,则按第二个数的倒序排
int[][] data1=new int[][]{{1,2},{3,1},{1,7,9},{2,1,4}};
Arrays.sort(data1,(a,b)->{
if(a[0]==b[0]) return b[1]-a[1];
return a[0]-b[0];
});
System.out.println("排序好的数组="+Arrays.deepToString(data1));
2)输出单维数组和多维数组
Integer[] data=new Integer[]{3,2,5,3,6,2,6,1};
System.out.println("排序好的数组="+Arrays.toString(data));
int[][] data1=new int[][]{{1,2},{3,1},{1,7,9},{2,1,4}};
System.out.println("排序好的数组="+Arrays.deepToString(data1));
3)本体的核心思想就是找最小右边界问题,这也是比较难想的一点。
第二题:435. 无重叠区间(hard题)
- 题目说明
这一题暂时没做 - 求解思路
- . 求解步骤
- 代码展示
- 补充说明
第三题:#763.划分字母区间
- 题目说明
- 求解思路
1)遍历每一个数,如果找到它在数组中最远位置,那么就一直更新找的区间。 - . 求解步骤
1) 首先写一个方法,输入某个值,找到在这个位置上的最大下标
2)遍历全局,如果小于初始位置最大下表,就一直更新最大值;
3)如果等于下标值,那么就输出位数,然后进入下一个地方。 - 代码展示
class Solution {
public List<Integer> partitionLabels(String s) {
//核心思想:从头开始遍历:调用method方法,找到不重复的最远距离;如果重合了,那么从下一个开始。
List<Integer> list=new ArrayList<>();
int befor=0;
int i=0;
int max=method(s,i,s.charAt(0));
while(i<s.length()){
if(i<max ){
max=Math.max(max,method(s,i,s.charAt(i)));
}
if(i==max){
list.add(i-befor+1);
befor=i+1;
if(i<s.length()-1) max=method(s,i,s.charAt(i+1));
}
i++;
}
return list;
}
//方法:一个字符在数组中最远的下标
public static int method(String s,int b,char a){
int size=0;
for(int i=b;i<s.length();i++){
if(s.charAt(i)==a){
size=i;
}
}
return size;
}
}
- 补充说明
- s.charAt():表示字符串某个位置的值。
第四题:56. 合并区间
- 题目说明
- 求解思路
1)先进行排序,然后比较前后两个数是否需要合并,并且不停的更新。 - . 求解步骤
1)重写sort方法进行排序
2)后者与前者有交集,则合并。 - 代码展示
class Solution {
public int[][] merge(int[][] intervals) {
List<int[]> list=new ArrayList<>();
//1)首先进行排序(根据第一个数值大小正序排列)
Arrays.sort(intervals,(a,b)->{
return a[0]-b[0];
});
System.out.println("intervals="+Arrays.deepToString(intervals));
//2)只有相邻的两个元素存在重叠情况
list.add(intervals[0]);
for(int i=1;i<intervals.length;i++){
int[] last=list.get(list.size()-1);
//(1)情况一:后者与前者有交集,则合并
if(intervals[i][0]<=last[1]){
int[] temp=new int[]{last[0],Math.max(last[1],intervals[i][1])};
list.set(list.size()-1,temp);
continue;
}
list.add(intervals[i]);
}
//3)把集合转变为二维数组
int[][] result=new int[list.size()][];
for(int i=0;i<list.size();i++){
result[i]=list.get(i);
}
return result;
}
//方法,输出数组
}
- 补充说明
1)对数组和集合的转变需要非常熟悉。