[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 };
[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 };
[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 */
[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 };
[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 };
[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 };