leetcode 贪心_【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 classSolution {4 public:5 static bool cmp(pair& a, pair&b) {6 return a.second

9 int findMinArrowShots(vector>&points) {10 sort(points.begin(), points.end(), cmp);11 vector 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 returnans;30 }31 };

View Code

[455] Assign Cookies [Easy]

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

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

1 //wyzhang

2 classSolution {3 public:4 int findContentChildren(vector& g, vector&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

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 classSolution {5 public:6 static bool cmp(pair a, pairb) {7 if(a.first ==b.first) {8 return a.second b.first;11 }12

13 vector> reconstructQueue(vector>&people) {14 sort(people.begin(), people.end(), cmp);15 vector>ans;16 for(vector>::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 returnans;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 classSolution {5 public:6 int canCompleteCircuit(vector& gas, vector&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 classSolution {12 public:13 static boolcmp(Interval a, Interval b) {14 if (a.end ==b.end) {15 return a.start &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 classSolution {2 public:3 vector maxNumber(vector& nums1, vector& nums2, intk) {4 vectorans;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 a =findMax(nums1, len1);14 vector b =findMax(nums2, len2);15 cout << vector2string(a) < res =merge(a, b);18 compare(ans, res);19 len1++, len2--;20 }21 returnans;22 }23

24 vector findMax(vector num, intlen) {25 vectorans(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 returnans;42 }43

44 //merge的时候不能只看某一位是否大,而是应该看组成的数是否大

45 vector merge (vector& a, vector&b) {46 if (a.empty()) returnb;47 if (b.empty()) returna;48 vectorans;49 int idx1 = 0, idx2 = 0;50 while (idx1 < a.size() && idx2 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

69 } else{70 while (idx1

77 void compare (vector& ans, vector&res) {78 if(ans.empty()) {79 ans =res;80 return;81 }82 if (ans.size() !=res.size()) {83 cout << "sth wrong" <ans[i]) {89 ans =res;90 break;91 } else{92 break;93 }94 }95 return;96 }97

98 bool isGreater(const vector& a, int i, const vector& b, intj) {99 for ( ; i < a.size() && j < b.size(); ++i, ++j) {100 if (a[i] b[j]) {103 return true;104 }105 }106 return i !=a.size();107 }108

109

110 string vector2string(vectora) {111 string s = "";112 for(auto ele : a) {113 s +=to_string(ele);114 }115 returns;116 }117

118 };

View Code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值