文章目录
今日知识总结
- 贪心的思想:总是作出当前看来最好的选择,不从整体上的最优进行考虑,局部最优解
- 例子:对于一个全是正整数的数组,求两数相乘的最大乘积,那么一定是最大的和次大的乘积
题目分析
-
-
题目链接:https://leetcode-cn.com/problems/maximum-product-difference-between-two-pairs/
-
思路:最大的两个数的乘积,减去最小的两个数的乘积一定是我们要求的最终解结果,给数组进行排序,找到最大值,次大值,最小值,次小值即可
-
代码:
class Solution { public: int maxProductDifference(vector<int>& nums) { int len = nums.size(); sort( nums.begin(), nums.end()); int a = nums[len - 1]; int b = nums[len - 2]; int c = nums[0]; int d = nums[1]; return a * b - c * d; } };
-
-
-
题目链接:https://leetcode-cn.com/problems/largest-perimeter-triangle
-
思路:首先确定三角形最长的边,再从最长的边反向遍历找比它小的两条边,能构成三角形就一定是最大的三角形周长
-
代码:
class Solution { public: int largestPerimeter(vector<int>& nums) { int len = nums.size(); int max = 0; sort(nums.begin(), nums.end()); for(int i = len - 1; i - 2 >= 0; i--){ if(nums[i] < nums[i - 1] + nums[i - 2]) { //cout << "next"; if(max < nums[i] + nums[i - 1] + nums[i - 2]){ max = nums[i] + nums[i - 1] + nums[i - 2]; break; } } // cout << nums[i]; } return max; } };
-
-
-
题目链接:https://leetcode-cn.com/problems/array-partition-i/
-
思路:要想得到最大的min值和,最大的和次大的组队,留下次大的,那么可以先将数组进行从小到大的排序,那么在偶数位上的一定是相对较小的
-
代码:
class Solution { public: int arrayPairSum(vector<int>& nums) { sort(nums.begin(), nums.end()); int max = 0; for(int i = 0; i < nums.size() - 1; i += 2){ max += nums[i]; } return max; } };
-
-
-
题目链接:https://leetcode-cn.com/problems/boats-to-save-people/
-
思路:判断能否两个人能否同时乘船,可以看最轻的人和最重的人,如果能,就变成了人数每次减二,不能这个人只能自己乘一个船,人数每次减一
-
代码:
class Solution { public: int numRescueBoats(vector<int>& people, int limit) { int ans = 0; sort(people.begin(), people.end()); int r = people.size() - 1; int l = 0; while(l <= r){ if(l == r) { ans++; break; } else if(people[l] + people[r] <= limit){ r --; l ++; ans++; } else if(people[l] + people[r] > limit){ r --; ans++; } } return ans; } };
-
-
-
题目链接:https://leetcode-cn.com/problems/wiggle-sort-ii/
-
思路:技术位置上从大到小排,偶数位置上也是从大到小排
-
代码:
class Solution { public: void wiggleSort(vector<int>& nums) { int len = nums.size() - 1; sort(nums.begin(), nums.end()); vector<int> ans(len + 1); int r = len; for(int i = 1; i <= len; i += 2){ ans[i] = nums[r--]; } for(int i = 0; i <= len; i += 2){ ans[i] = nums[r--]; } for(int i = 0; i < nums.size(); i++){ nums[i] = ans[i]; } } };
-
-
-
题目链接:https://leetcode-cn.com/problems/assign-cookies/
-
思路:如果最小分量的饼干无法满足胃口最小的孩子,那么这块饼干就直接被丢弃,看看先一块饼干能否满足孩子
-
代码:
class Solution { public: int findContentChildren(vector<int>& g, vector<int>& s) { sort(g.begin(), g.end()); sort(s.begin(), s.end()); int cnt = 0; int flg = 0, i = 0; while(i < g.size()){ if(flg == s.size()) break; if(g[i] <= s[flg]) { cnt++; i++; } flg++; } return cnt; } };
-
-
-
题目链接:https://leetcode-cn.com/problems/minimum-operations-to-make-the-array-increasing/
-
思路:判断相邻的两个数是不是递增,如果是,就判断下一组,如果不是就让这个数变成前一个加一,当前这个数的值与之前的值的差就是这两个数之间最小改变次数,如此只需要遍历一遍数组就可以这个数组的最小改变次数了
-
代码:
class Solution { public: int minOperations(vector<int>& nums) { int len = nums.size(); if(len == 1) return 0; int cnt = 0; for(int i = 1; i < len; i++){ if(nums[i] > nums[i - 1]) continue; else{ cnt += (nums[i - 1] - nums[i] + 1); nums[i] = nums[i - 1] + 1; } } return cnt; } };
-
-
-
题目链接:https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique/
-
思路:这一题只比上一题多了一个排序的步骤,如果数组严格递增,那么这个数组中的每个值一定是唯一的,如果只是严格递增那无法保证增量最小,那么可以给数组排序,保证数组是递增的,再使递增变成严格递增,这样就可以保证增量最小了
-
代码:
class Solution { public: int minIncrementForUnique(vector<int>& nums) { sort(nums.begin(), nums.end()); int len = nums.size(); if(len == 1) return 0; int cnt = 0; for(int i = 1; i < len; i++){ if(nums[i] > nums[i - 1]) continue; else{ cnt += (nums[i - 1] - nums[i] + 1); nums[i] = nums[i - 1] + 1; } } return cnt; } };
-
-
-
题目链接:https://leetcode-cn.com/problems/valid-triangle-number/
-
思路:
-
代码:
class Solution { public: int triangleNumber(vector<int>& nums) { int len = nums.size(); sort(nums.begin(), nums.end()); if(len < 3) return 0; int cnt = 0; int j = 0, k = 0; for(int i = 0; i < len; ++i){ j = i + 1; k = j + 1; while(j < len){ while( k < len){ if(nums[i] + nums[j] <= nums[k]) break; ++k; } cnt += k - j - 1; ++j; if(k == j) k++; } } return cnt; } };
-