解决第三题时的方法和leetcode上45.Jump Game II也很像,都是用到了贪心的思想。
先说leetcode上的那道题,初始化lastMax = 0, curMax = 0两个指针,每次遍历i <= lastMax的所有nums[i]的值,并计算i+nums[i](相当于计算每个i能到达的最大位置下标)取最大的那个,进而更新curMax和lastMax指针。注意当lastMax>=length-1时就得到最终跳跃的步数,而当某一次的while循环中lastMax == curMax说明不可能跳到数组最后一个下标。代码如下:
class Solution {
    public int jump(int[] nums) {
       if(nums == null || nums.length <= 1){
           return 0;
       }
        int step = 0, lastMax = 0, curMax = 0, i = 0;
        while(lastMax < nums.length-1){
            while(i <= lastMax && i < nums.length){
                curMax = Math.max(curMax, i+nums[i]);
                i += 1;
            }
            if(lastMax == curMax){
                return -1;
            }
            step += 1;
            lastMax = curMax;
        }
        return step;
    }
}
再说这道题,将每个炮塔的控制范围按照起始点排序以后,每次遍历list.get(i).start <= end(当前区间终点)的所有区间,取终点最大的那个,进而更新end。注意当某一次的while循环中出现end < list.get(i).start的情况时返回-1(这也就是为什么要按照起点排序,因为后面i+1、i+2……的start会更大),另外当遍历结束后的那个end小于l时也返回-1。代码如下:
import java.util.Scanner;
import java.util.*;
public class Main {
    public static class Pair{
        int start, end;
        public Pair(int s, int e){
            this.start = s;
            this.end = e;
        }
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int answer = 0;
        int n = sc.nextInt();
        int l = sc.nextInt();
        List<Pair> list = new ArrayList<Pair>();
        for(int i = 0; i < n; i++){
            int s = sc.nextInt();
            int e = sc.nextInt();
            Pair p = new Pair(s, e);
            list.add(p);
        }
        Collections.sort(list, new Comparator<Pair>() {
            @Override
            public int compare(Pair o1, Pair o2) {
                if(o1.start != o2.start){
                    return o1.start - o2.start;
                }else{
                    return o1.end - o2.end;
                }

            }
        });
        if(n == 1){
            if(list.get(0).start>0 || list.get(0).end<l){
                System.out.println(-1);
            }else{
                System.out.println(1);
            }
        }else{
            int start = list.get(0).start;
            int end = list.get(0).end;
            if(start > 0){
                System.out.println(-1);
            }else{
                answer += 1;
                int i =1;
                while(i < n){
                    if(end >= l){
                        System.out.println(answer);
                        return;
                    }
                    if(end < list.get(i).start){
                        System.out.println(-1);
                        return;
                    }
                    int newEnd = -1;
                    while(i < n && list.get(i).start <= end){
                        newEnd = Math.max(list.get(i).end, newEnd);
                        i += 1;
                    }
                    answer += 1;
                    end = newEnd;
                }
                if(end < l){
                    System.out.println(-1);
                }else{
                    System.out.println(answer);
                }
            }
        }
    }
}