1.无重复区间
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if(intervals.length==0) return 0;
//贪心算法:区间调度,找到最多不重合子区间,用集合长度减去不重合子区间个数就是答案
//1.让二维数组按照每个一维数组的end进行排序(从小到大)
//2.找到最小的end,然后排除start<end的那些区间,重复这个过程
int n=intervals.length;
Arrays.sort(intervals,new Comparator<int[]>(){
public int compare(int[] a,int[] b){
return a[1]-b[1];//按照end升序排序
}
});
//结果最小为1
int res=1;
int minEnd=intervals[0][1];
for(int i=1;i<intervals.length;i++){
int start=intervals[i][0];
//找到start>end的那些区间,这些是不互相重叠的
if(start>=minEnd){
res++;
minEnd=intervals[i][1];
}
}
return intervals.length- res;
}
}
2.用最少数量的箭引爆气球
class Solution {
public int findMinArrowShots(int[][] points) {
int n=points.length;
if(n==0) return 0;
int count=1;
Arrays.sort(points,new Comparator<int[]>(){
public int compare(int[] a,int[] b){
if(a[1]>b[1]){
return 1;
}else if(a[1]<b[1]){
return -1;
}else{
return 0;
}
}
});
int minEnd=points[0][1];
for(int i=1;i<n;i++){
int start=points[i][0];
if(start>minEnd){
count++;
minEnd=points[i][1];
}
}
return count;
}
}
3.跳跃游戏
class Solution {
public boolean canJump(int[] nums) {
//使用贪心算法
int n=nums.length;
int farthest=0;
for(int i=0;i<n-1;i++){
farthest=Math.max(farthest,nums[i]+i);
//遇到0卡住,跳不了
if(farthest<=i) return false;
}
return farthest>=n-1;
}
}
使用贪心算法,计算出每步跳跃的最大距离,更新全局的跳跃最远距离
动归解法:
class Solution {
int[] memo;
public int jump(int[] nums) {
//1.使用动归,自顶向下求解每个位置的最小跳跃数,使用memo备忘录消除重叠子问题
memo=new int[nums.length];
Arrays.fill(memo,nums.length);
return dp(nums,0);
}
//p为位置索引,dp(nums,p)表示从索引p到最后一个位置的最小跳跃数
public int dp(int[] nums,int p){
int n=nums.length;
//base case,到达最后一个位置之后不需要再跳跃
if(p>=n-1){
return 0;
}
//备忘录中有则直接返回
if(memo[p]!=n){
return memo[p];
}
//当前位置能够跳跃的步数
int steps=nums[p];
//遍历每个步数
for(int i=1;i<=steps;i++){
//子问题求解,从当前位置往下跳i步
int subproblem=dp(nums,p+i);
memo[p]=Math.min(memo[p],subproblem+1);//往下跳一步需要加1
}
return memo[p];
}
}
贪心解法:
class Solution {
public int jump(int[] nums) {
//2.贪心解法,每次跳能够到达的最远位置
int n=nums.length;
int end=0;//跳跃的最远位置(索引)
int steps=0;//记录跳跃次数
int farthest=0;//局部最远跳跃位置变量
for(int i=0;i<n-1;i++){
farthest=Math.max(farthest,nums[i]+i);
//当索引已经到达之前跳跃的最远位置时,重新判断当前可以到达的最远位置end,并将跳跃次数加1
if(end==i){
steps++;
end=farthest;
}
}
return steps;
}
}