• 算法通关村第17关【白银】| 贪心高频问题


    区间问题

    1. 会议室(判断区间是否重叠)

    思路:很容易理解一个人不可能同时出席两场会议,也就是会议时间不能重叠。先按照开始时间排序,逐个比较下一个会议开始时间是否大于前一个会议的结束时间

    1. public static boolean canAttendMeetings(int[][] intervals) {
    2. // 将区间按照会议开始实现升序排序
    3. Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]);
    4. // 遍历会议,如果下一个会议在前一个会议结束之前就开始了,返回 false。
    5. for (int i = 1; i < intervals.length; i++) {
    6. if (intervals[i][0] < intervals[i - 1][1]) {
    7. return false;
    8. }
    9. }
    10. return true;
    11. }

    2. 合并区间

    思路:合并有重叠的区间然后加入结果集,就是需要注意一些边界

    1. class Solution {
    2. public int[][] merge(int[][] intervals) {
    3. if(intervals.length==1){
    4. return intervals;
    5. }
    6. Arrays.sort(intervals,(v1,v2)->v1[0]-v2[0]);
    7. ArrayList<int[]> list = new ArrayList<int[]>();
    8. int i = 1;
    9. while(i
    10. if(intervals[i-1][1]0]){
    11. list.add(intervals[i-1]);
    12. i++;
    13. }
    14. int k = i-1;
    15. while(i1]>=intervals[i][0]){
    16. intervals[k][1] = Math.max(intervals[i][1],intervals[k][1]);
    17. i++;
    18. }
    19. i++;
    20. list.add(intervals[k]);
    21. if(i == intervals.length){
    22. list.add(intervals[i-1]);
    23. }
    24. }
    25. return list.toArray(new int[list.size()][]);
    26. }
    27. }

    3. 插入区间

    思路:无重复区间直接添加进结果集,重复的进行区间合并(左取小,右取大)

    1. class Solution {
    2. public int[][] insert(int[][] intervals, int[] newInterval) {
    3. int left = newInterval[0];
    4. int right = newInterval[1];
    5. boolean placed = false;
    6. List<int[]> ansList = new ArrayList<int[]>();
    7. for (int[] interval : intervals) {
    8. if (interval[0] > right) {
    9. // 在插入区间的右侧且无交集
    10. if (!placed) {
    11. ansList.add(new int[]{left, right});
    12. placed = true;
    13. }
    14. ansList.add(interval);
    15. } else if (interval[1] < left) {
    16. // 在插入区间的左侧且无交集
    17. ansList.add(interval);
    18. } else {
    19. // 与插入区间有交集,计算它们的并集
    20. left = Math.min(left, interval[0]);
    21. right = Math.max(right, interval[1]);
    22. }
    23. }
    24. if (!placed) {
    25. ansList.add(new int[]{left, right});
    26. }
    27. int[][] ans = new int[ansList.size()][2];
    28. for (int i = 0; i < ansList.size(); ++i) {
    29. ans[i] = ansList.get(i);
    30. }
    31. return ans;
    32. }
    33. }

    字符串分割

    思路:很容易想到首先遍历一遍获得每个字母的最后出现的下标位置,怎么找出包含当前字母最后一次出现的最短的片段呢?也就是在第二次遍历中:当前遍历的位置正好是前面所有字母中最长的end位置

    1. class Solution {
    2. public List partitionLabels(String s) {
    3. int[] last = new int[26];
    4. int len = s.length();
    5. for(int i = 0;i
    6. last[s.charAt(i)-'a'] = i;
    7. }
    8. int end = 0;
    9. List list = new ArrayList();
    10. int start = 0;
    11. for(int i = 0;i
    12. //当前字母的end是最后的end
    13. end = Math.max(last[s.charAt(i)-'a'],end);
    14. if(i == end){
    15. list.add(i - start + 1);
    16. start = end+1;
    17. }
    18. }
    19. return list;
    20. }
    21. }

    加油站

    思路:如果每个加油站的剩余油量总和大于等于0那么就是能跑完全程,当前剩余油量小于零则不能从i之前的加油站出发,剩余总油量固定左边小右边就大

    1. class Solution {
    2. public int canCompleteCircuit(int[] gas, int[] cost) {
    3. int total = 0;
    4. int cur = 0;
    5. int start = 0;
    6. for(int i = 0;i
    7. total += gas[i] - cost[i];
    8. cur += gas[i] - cost[i];
    9. if(cur<0){
    10. start = i + 1;
    11. cur = 0;
    12. }
    13. }
    14. if(total<0){
    15. return -1;
    16. }else{
    17. return start;
    18. }
    19. }
    20. }

  • 相关阅读:
    细粒度特征提取和定位用于目标检测:PPCNN
    九月医疗宣传日|适合幼小学宣传的几款医疗模板
    Vim基础
    企业应用开发中.NET EF常用哪种模式?
    金融行业基于 DELL EMC 高端存储的核心系统实践经验分享
    JAVA学习日记1——JAVA简介及第一个java程序
    音频驱动嘴型的视频数字人虚拟主播工具motionface replay使用教程
    #paypay付款测试#
    【C语言】刷题笔记 Day1
    与tcp协议有关的几个知识点
  • 原文地址:https://blog.csdn.net/Candy___i/article/details/133675981