【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

 

posted @ 2017-03-28 20:35  zhangwanying  阅读(370)  评论(0编辑  收藏  举报