赞
踩
两个数对
(a, b)
和(c, d)
之间的 乘积差 定义为(a * b) - (c * d)
。例如,
(5, 6)
和(2, 7)
之间的乘积差是(5 * 6) - (2 * 7) = 16
。
给你一个整数数组nums
,选出四个 不同的 下标w、x、y
和z
,使数对(nums[w], nums[x])
和(nums[y], nums[z])
之间的 乘积差 取到 最大值 。返回以这种方式取得的乘积差中的 最大值 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-product-difference-between-two-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
返回两个数对的最大值,那么就需要将数组中最大和次大的数相乘、最小与次小的数相乘,前一项减去后一项即为最大乘积差。对数组排序即可解答本题
int cmp(const void* a, const void *b)
{
return *(int *)a - *(int *)b;
}
int maxProductDifference(int* nums, int numsSize){
qsort(nums, numsSize, sizeof(int), cmp); //排序
return nums[numsSize - 1] * nums[numsSize - 2] - nums[0] * nums[1];
}
给定长度为
2n
的整数数组nums
,你的任务是将这些数分成n
对, 例如(a1, b1), (a2, b2), ..., (an, bn)
,使得从1
到n
的min(ai, bi)
总和最大。返回该 最大总和 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/array-partition-i
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
每一次选取的是数对的较小值,要使得总和最大,那么每次拆分的数对中的较小值应该仅次于较大值。根据这个条件,我们可以对数组进行排序,然后选取偶数位的元素相加即可
int cmp(const void* a, const void *b)
{
return *(int *)a - *(int *)b;
}
int arrayPairSum(int* nums, int numsSize){
//先排序
qsort(nums, numsSize, sizeof(int), cmp);
int i;
int ret = 0;
for(i = 0; i < numsSize; i += 2)
{
ret += nums[i]; //取偶数位的值相加
}
return ret;
}
给你一个整数数组
nums
,将它重新排列成nums[0] < nums[1] > nums[2] < nums[3]...
的顺序。你可以假设所有输入数组都可以得到满足题目要求的结果。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/wiggle-sort-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
显而易见这题是需要进行排序的,问题在于排序之后怎么排列元素,观察题目给出的示例,可以看到较大值一定是在奇数位的,按照升序排列之后,较大的元素值一定是在数组的右半边,那么我们是不是可以先从数组的最右边开始遍历,将元素按指定位置插入新数组中,较大值插入完毕后,剩下的就是较小值。
int cmp(const void *a, const void* b) { return *(int *)a - *(int *)b; } void wiggleSort(int* nums, int numsSize){ qsort(nums, numsSize, sizeof(int), cmp); int ans[numsSize]; int i; for(i = 0; i < numsSize; ++i) { ans[i] = nums[i]; //赋值到新数组 } int r = numsSize - 1; //注意是从大到小插入 for(i = 1; i < numsSize; i += 2) //先插较大值 { nums[i] = ans[r--]; } for(i = 0; i < numsSize; i += 2) //在插较小值 { nums[i] = ans[r--]; } }
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子
i
,都有一个胃口值g[i]
,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干j
,都有一个尺寸s[j]
。如果s[j] >= g[i]
,我们可以将这个饼干j
分配给孩子i
,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/assign-cookies
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
本题其实就是求s数组中的元素大于等于g数组中元素的个数
int cmp(const void* a, const void* b) { return *(int *)a - *(int *)b; } int findContentChildren(int* g, int gSize, int* s, int sSize){ qsort(g, gSize, sizeof(int), cmp); //先排序 qsort(s, sSize, sizeof(int), cmp); int p2 = sSize - 1; int p1 = gSize - 1; int cnt = 0; //统计满足的孩子的数量 //先满足胃口最大的孩子 while(p1 >= 0 && p2 >= 0) { if(s[p2] >= g[p1]) { cnt++; p1--; p2--; } else { p1--; } } return cnt; }
给你一个整数数组
nums
(下标从 0 开始)。每一次操作中,你可以选择数组中一个元素,并将它增加 1 。比方说,如果
nums = [1,2,3]
,你可以选择增加nums[1]
得到nums = [1,3,3]
。
请你返回使nums
严格递增 的 最少 操作次数。我们称数组
nums
是 严格递增的 ,当它满足对于所有的0 <= i < nums.length - 1
都有nums[i] < nums[i+1]
。一个长度为 1 的数组是严格递增的一种特殊情况。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-operations-to-make-the-array-increasing
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
求最小的操作次数,只需要比前面的元素大1就行。
- 双层循环可以解答本题,外层循环控制前一个元素,内层循环控制后一个元素。
- 使用单层循环加条件语句。外循环控制前一个元素,条件语句保证后一个元素比前一个元素大
int minOperations(int* nums, int numsSize){ int i; int cnt = 0; int pre = nums[0] + 1; //只需要比前一个元素大1即可 for(i = 1; i < numsSize; ++i) { if(pre < nums[i]) { pre = nums[i] + 1; //小于更新为当前nums[i]的元素并加1 } else { cnt += pre - nums[i]; //统计数量 ++pre; //大于就加1,直到小于更新pre值 } } return cnt; } /* 模拟:[1, 1, 1] 第一次 pre = 2 大于 nums[1] cnt统计前一个元素和后一个元素的差值(即操作数) cnt = 1; 第二次 pre = 3 大于 nums[2] cnt = 1 + 3 - 1; 所以最终结果为3。 */
给你一个整数数组
nums
。每次 move 操作将会选择任意一个满足0 <= i < nums.length
的下标i
,并将nums[i]
递增1
。返回使
nums
中的每个值都变成唯一的所需要的最少操作次数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
要保证数组中每一个元素是唯一的增量,需要找出数组中不唯一的值,利用排序先将数组中相同的值放在一起,然后参照上一题的思路求解
int cmp(const void* a, const void *b) { return *(int *)a - *(int *)b; } int minIncrementForUnique(int* nums, int numsSize){ qsort(nums, numsSize, sizeof(int), cmp); int i; int pre = nums[0] + 1; int cnt = 0; for(i = 1; i < numsSize; ++i) { if(pre < nums[i]) { pre = nums[i] + 1; } else { cnt += pre - nums[i]; ++pre; } } return cnt; }
给定由一些正数(代表长度)组成的数组
A
,返回由其中三个长度组成的、面积不为零的三角形的最大周长。如果不能形成任何面积不为零的三角形,返回
0
。
利用贪心算法思想,要想得到最大的周长的值,只需要判断该数组中最大的三个元素是否构成三角形。
- 构成三角形的条件:任意两边之和大于第三边。三个元素任意两个组合相加判断是否大于第三边固然是可以的,但是操作复杂且时间复杂度高,不建议使用。
- 像这种情况我们可以先进行排序,排序之后我们发现
a < b < c
已经得出两个结论b + c > a
和a + c < b
,现在只需要比较a + b > c
- 最后求最大周长的值
int cmp(const void* a, const void *b) { return *(int *)a - *(int *)b; } int largestPerimeter(int* nums, int numsSize){ if(numsSize < 2) //两个元素是无法构成三角形的 { return 0; } qsort(nums, numsSize, sizeof(int), cmp); int i; //从最后的元素开始遍历,只要能构成三角形,那么结果就为最大周长 for(i = numsSize - 1; i >= 2; --i) { if(nums[i - 2] + nums[i - 1] > nums[i]) { return nums[i - 2] + nums[i - 1] + nums[i]; } } return 0; }
第 i 个人的体重为
people[i]
,每艘船可以承载的最大重量为limit
。每艘船最多可同时载两人,但条件是这些人的重量之和最多为
limit
。返回载到每一个人所需的最小船数。(保证每个人都能被船载)。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/boats-to-save-people
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
要求所需最小船数,就必须保证每次乘坐的是能乘坐的最大值。这种情况使用排序就比较方便对其进行求解。
- 第一步,排序
- 第二步,判断最大的体重和最小体重能否一起乘坐一艘船,能就一起走,不能就先让体重大的人先走
- 第三步,返回结果
int cmp(const void* a, const void *b) { return *(int *)a - *(int *)b; } int numRescueBoats(int* people, int peopleSize, int limit){ //体重people[i] , 船能承载的最大体重是limit //同时载两人 //求载到每一个人所需的最小船数 qsort(people, peopleSize, sizeof(int), cmp); int ans = 0; //统计船的数量 int left = 0; int right = peopleSize - 1; while(left <= right) { if(left == right) //只有一个人了,直接走 { ++ans; break; } else if(people[left] + people[right] > limit) //最小的与最大的比较,如果大于就让最大的先走 { ++ans; right--; } else { ++ans; right--; left++; } } return ans; }
给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。
(参照的官方思路)先排序,在二分查找有效三角形的个数。
- 假定数组
[a ,b ,c]
, 排序完成后a < b < c
,分析数组中元素可以得出两个结论b + c > a
和a + c < b
,然后通过二分法查找满足a + b > c
的元素个数。- 统计mid左边到
j
位置的元素个数。
int cmp(int *a, int *b) { return *a - *b; } int triangleNumber(int* nums, int numsSize){ int cnt = 0; //统计有效三角形的数量 //先排序,后比较 int i, j; qsort(nums, numsSize, sizeof(int), cmp); for(i = 0; i < numsSize; ++i) { for(j = i + 1; j < numsSize; ++j) { int left = j + 1; int right = numsSize - 1; int k = j; //防止枚举a,b的出现0的时候,二分查找失败 while(left <= right) { int mid = left + (right - left) / 2; if(nums[mid] < nums[j] + nums[i]) { k = mid; left = mid + 1; } else { right = mid - 1; } } cnt += k - j; //统计每次循环有效三角形的个数 } } return cnt; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。