zoukankan      html  css  js  c++  java
  • 【LeetCode】贪心

    [452] Minimum Number of Arrows to Burst Balloons [Medium]

    给一堆线段,使用最少的arrow,穿过所有的线段。陈题,第一条线段的终点。

    Input:
    [[10,16], [2,8], [1,6], [7,12]]
    
    Output:
    2
    
    Explanation:
    One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x = 11 (bursting the other two balloons).
     1 // 陈题。 第一条线段的终点。
     2 //wyzhang
     3 class Solution {
     4 public:
     5     static bool cmp(pair<int, int>& a, pair<int, int>& b) {
     6         return a.second < b.second;
     7     }
     8 
     9     int findMinArrowShots(vector<pair<int, int>>& points) {
    10         sort(points.begin(), points.end(), cmp);
    11         vector<bool> valid_segments(points.size(), true);
    12 
    13         int ans = 0;
    14         for (size_t i = 0; i < points.size(); ++i) {
    15             if(!valid_segments[i]) { // balloon has been shot
    16                 continue;
    17             }
    18             const int end = points[i].second;
    19             for (size_t j = i + 1; j < points.size(); ++j) {
    20                 if (!valid_segments[j]) {
    21                     continue;
    22                 }
    23                 if (end >= points[j].first) {
    24                     valid_segments[j] = false;
    25                 }
    26             }
    27             ans++;
    28         }
    29         return ans;
    30     }
    31 };
    View Code

    [455] Assign Cookies [Easy]

    一堆孩子,一堆饼,每个孩子分一块饼,每个孩子对饼的质量有要求,只有达到孩子的要求,他们才会满足,设计一个策略,使得最多的孩子得到满足。

    思路:两个数组排个序,然后两个指针直接给。

     1 //wyzhang
     2 class Solution {
     3 public:
     4     int findContentChildren(vector<int>& g, vector<int>& s) {
     5         sort(g.begin(), g.end());
     6         sort(s.begin(), s.end());
     7         int ans = 0;
     8         size_t i = 0, j = 0;
     9         while (i < g.size() && j < s.size()) {
    10             if (g[i] <= s[j]) {
    11                 ++i, ++j;
    12                 ans++;
    13             } else {
    14                 ++j;
    15             }
    16         }
    17         return ans;
    18     }
    19 };
    View Code

    [406] Queue Reconstruction by Height [Medium]

    给一群人按身高排序,每个人都有两个属性(h,k),排序的要求是这个人身高是h, 前面有k个人大于等于这个人的身高。

    Input:
    [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
    
    Output:
    [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

    思路:按照身高分组,然后做插入排序

     1 //贪心
     2 //按照身高分组,然后做插入排序
     3 //Space: O(n), time:O(n)
     4 class Solution {
     5 public:
     6     static bool cmp(pair<int, int> a, pair<int, int> b) {
     7         if(a.first == b.first) {
     8             return a.second < b.second;
     9         }
    10         return a.first > b.first;
    11     }
    12 
    13     vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) {
    14         sort(people.begin(), people.end(), cmp);
    15         vector<pair<int, int>> ans;
    16         for(vector<pair<int, int>>::size_type i = 0; i < people.size(); ++i) {
    17             if (people[i] == people[0]) {
    18                 ans.push_back(people[i]);
    19                 continue;
    20             } 
    21             if (people[i].second == ans.size()) {
    22                 ans.push_back(people[i]);
    23             } else {
    24                 auto pos = ans.begin() + people[i].second;
    25                 ans.insert(pos, people[i]);
    26             }
    27         }
    28         return ans;
    29     }
    30 };
    31 
    32 /*
    33 *先对已有的数组进行排序。按照高度降序排列,如果高度一样,按照k的值升序排列。这样比如一开始7,0   7,1   7,2就会排好,然后比如说后面有一个6,1, 说明只有一个大于或等于它,又因为比6大的已经全部取出。所以把它放在位置1,这样就变成7,0  6,1  7,1  7,2.然后比如又有一个5,0.就放在位置0,以此类推
    34 */
    View Code

    [134] Gas Station [Medium]

    环形路上有很多加油站,油箱容量无上限,每个加油站有gas[i]的汽油,从i到i+1个加油站需要花费cost[i]的汽油。问能不能找到个起点使得汽车跑完全程。

    思路见代码注释

     1 //O(n^2) 超时
     2 //遍历一轮加油站, 如果当前这个station不行的话,从起点到当前station都不能做起点,因为他们都到不了i+1个加油站
     3 //所以,只能从i+1开始选起点。 还有一个限制条件就是汽油的总和小于花费的总和的话,永远跑不完。
     4 class Solution {
     5 public:
     6     int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
     7         int car = 0;
     8         int start = 0;
     9         int total = 0;
    10         const int N = gas.size();
    11         for (int i = 0; i < gas.size(); ++i) {
    12             car += gas[i] - cost[i];
    13             if(car < 0) {
    14                 car = 0;
    15                 start = i + 1;
    16             }
    17             total += gas[i] - cost[i];
    18         }
    19         return (total >= 0) ? start : -1;
    20     }
    21 };
    View Code

    [435] Non-overlapping Intervals [Medium]

    有若干条线段,可能相互重叠,求删除最少的线段条数,使得每条线段都不重叠。

    经典题是给个时间区间让安排活动,在活动时间不冲突的情况下安排尽可能多的活动。

     1 //其实是如何在不重叠的情况下放下更多的线段。
     2 /**
     3  * Definition for an interval.
     4  * struct Interval {
     5  *     int start;
     6  *     int end;
     7  *     Interval() : start(0), end(0) {}
     8  *     Interval(int s, int e) : start(s), end(e) {}
     9  * };
    10  */
    11 class Solution {
    12 public:
    13     static bool cmp(Interval a, Interval b) {
    14         if (a.end == b.end) {
    15             return a.start < b.start;
    16         }
    17         return a.end < b.end;
    18     }
    19     int eraseOverlapIntervals(vector<Interval>& intervals) {
    20         if (intervals.empty()) {
    21             return 0;
    22         }
    23         sort(intervals.begin(), intervals.end(), cmp);
    24         int end = intervals[0].end;
    25         int cnt = 1;
    26         for (size_t i = 1; i < intervals.size(); ++i) {
    27             if (intervals[i].start >= end) {
    28                 ++cnt;
    29                 end = intervals[i].end;
    30             }
    31         }
    32         return intervals.size() - cnt;
    33     }
    34 };
    View Code

    [321] Create Maximum Number [Hard]

    给了两个数组,内容是0-9的数字,长度分别是m,n,和一个数字k。 有 m+n>=k。在保持两个数组每个数组的相对位置不变的情况下, 从两个数组中一共选出k个数,使得这个数最大。

     从num1里面选出len1个能组成最大数的元素, 从num2里面选出len2个能组成最大数的元素,然后合并。(合并有坑)

    合并不能直接归并排序,当两个数相等时,不能直接随便给一个,而是比较哪个数组组成的数字大就选那个数组。。。 

    比如说[6,7], [6,  0, 4] ,6相同的情况下应该比较7和 0, 7比0大, 所以选第一个数组中的6. 要是一直都一样,就选长的那个。

      1 class Solution {
      2 public:
      3     vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
      4         vector<int> ans;
      5         const int m = nums1.size(), n = nums2.size();
      6         int len1 = 0, len2 = k; //len1 增长, len2 减小
      7         while (len1 <= m && len2 >= 0) {
      8             if (len2 > n) {
      9                 len2--; ++len1;
     10                 continue;
     11             }
     12             //cout << "len1= " << len1 << " len2=" << len2 << endl;
     13             vector<int> a = findMax(nums1, len1);
     14             vector<int> b = findMax(nums2, len2);
     15             cout << vector2string(a) << endl;
     16             cout << vector2string(b) << endl;
     17             vector<int> res = merge(a, b);
     18             compare(ans, res);
     19             len1++, len2--;
     20         }
     21         return ans;
     22     }
     23     
     24     vector<int> findMax(vector<int> num, int len) {
     25         vector<int> ans(len);
     26         const int n = num.size();
     27         int j = 1;
     28         int start = 0;
     29         while (j <= len) {
     30             int temp = INT_MIN;
     31             for (int i = start; i < n-(len-j); ++i) {
     32                 if (num[i] > temp) {
     33                     temp = num[i];
     34                     start = i + 1;
     35                 }
     36             }
     37             ans[j-1] = temp;
     38             ++j;
     39         }
     40         //cout << __FUNCTION__ << " ans: "  << vector2string(ans) << endl;
     41         return ans;
     42     }
     43     
     44     //merge的时候不能只看某一位是否大,而是应该看组成的数是否大
     45     vector<int> merge (vector<int>& a, vector<int>& b) {
     46         if (a.empty()) return b;
     47         if (b.empty()) return a;
     48         vector<int> ans;
     49         int idx1 = 0, idx2 = 0;
     50         while (idx1 < a.size() && idx2 < b.size()) { 
     51             if (a[idx1] < b[idx2]) {
     52                 ans.push_back(b[idx2++]);
     53             } else if (a[idx1] > b[idx2]){
     54                 ans.push_back(a[idx1++]);
     55             } else {
     56                 if (isGreater(a, idx1, b, idx2) == true) { //a greater
     57                     ans.push_back(a[idx1++]);
     58                 } else {
     59                     ans.push_back(b[idx2++]);
     60                 }
     61             }
     62         }
     63         
     64         if (idx1 == a.size()) {
     65             while(idx2 < b.size()) {
     66                 ans.push_back(b[idx2++]);
     67             }
     68             
     69         } else {
     70             while (idx1 < a.size()) {
     71                 ans.push_back(a[idx1++]);
     72             }
     73         }
     74         return ans;
     75     }
     76     
     77     void compare (vector<int>& ans, vector<int>& res) {
     78         if(ans.empty()) {
     79             ans = res;
     80             return;
     81         }
     82         if (ans.size() != res.size()) {
     83             cout << "sth wrong" << endl;
     84         }
     85         for (size_t i = 0; i < ans.size(); ++i) {
     86             if (ans[i] == res[i]) {
     87                 continue;
     88             } else if (res[i] > ans[i]) {
     89                 ans = res;
     90                 break;
     91             } else {
     92                 break;
     93             }
     94         }
     95         return;
     96     }
     97     
     98     bool isGreater(const vector<int>& a, int i, const vector<int>& b, int j) {
     99         for ( ; i < a.size() && j < b.size(); ++i, ++j) {
    100             if (a[i] < b[j]) {
    101                 return false;
    102             } else if (a[i] > b[j]) {
    103                 return true;
    104             }
    105         }
    106         return i != a.size();
    107     }
    108     
    109     
    110     string vector2string(vector<int> a) {
    111         string s = "";
    112         for(auto ele : a) {
    113             s += to_string(ele);
    114         }
    115         return s;
    116     }
    117     
    118 };
    View Code
  • 相关阅读:
    中文乱码—Servlet—SpringMVC
    (转+整理)C# BinaryFormatter进行序列化与反序列化
    (转)C# 之泛型详解
    (转)C#中base关键字的几种用法
    (转)C# Where关键词的用法
    (转)c# 断言类
    (转+整理)C#中动态执行代码
    (转)c# control.Invoke control.BeginInvoke
    (转)c# String与StringBuilder
    (转)winform之ListView
  • 原文地址:https://www.cnblogs.com/zhangwanying/p/6636728.html
Copyright © 2011-2022 走看看