• 算法通关村第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. }

  • 相关阅读:
    Java培训之java8新特性程序代码
    IPETRONIK数采与第三方软件集成
    JSON 对象(object)
    动态规划算法学习三:0-1背包问题
    Git 学习笔记 | 版本控制和版本控制工具
    2023-2028中国稻谷行业市场 国稻种芯:未来趋势预测报告
    跨境电商必看!防关联浏览器在多店铺管理中的实际作用
    图扑数字孪生空冷机组,助推智慧电厂拥抱“双碳”
    Desoutter智能拧紧中枢Connect过压维修
    m基于MATLAB的通信系统仿真,包括信号源,载波信号,放大器,带宽滤波器,接收端包括放大器,带宽滤波器,载波解调,低通滤波器等
  • 原文地址:https://blog.csdn.net/Candy___i/article/details/133675981