一、
难度简单15
两个数对 (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])
之间的 乘积差 取到 最大值 。
返回以这种方式取得的乘积差中的 最大值 。
class Solution {
public:
int maxProductDifference(vector<int>& nums) {
sort(nums.begin(),nums.end());
if(nums.size()<4)return 0;
return nums[nums.size()-1]*nums[nums.size()-2]-nums[0]*nums[1];
}
};
class Solution {
public:
int maxProductDifference(vector<int>& nums) {
int Max1 = 0;
int Max0 = 0;
int Min0 = 10000000;
int Min1 = 10000000;
for(int i=0;i<nums.size();i++)
{
if(Max1<nums[i])
{
Max0=Max1;
Max1=nums[i];
}
else if(Max0<nums[i])
Max0=nums[i];
if(Min0>nums[i])
{
Min1=Min0;
Min0=nums[i];
}
else if(Min1>nums[i])Min1=nums[i];
}
return Max1*Max0-Min0*Min1;
}
};
---------------------------------------------------------------------------------------------------------------------------------
二、
难度简单286
给定长度为 2n
的整数数组 nums
,你的任务是将这些数分成 n
对, 例如 (a1, b1), (a2, b2), ..., (an, bn)
,使得从 1
到 n
的 min(ai, bi)
总和最大。
返回该 最大总和 。
示例 1:
输入:nums = [1,4,3,2] 输出:4 解释:所有可能的分法(忽略元素顺序)为: 1. (1, 4), (2, 3) -> min(1, 4) + min(2, 3) = 1 + 2 = 3 2. (1, 3), (2, 4) -> min(1, 3) + min(2, 4) = 1 + 2 = 3 3. (1, 2), (3, 4) -> min(1, 2) + min(3, 4) = 1 + 3 = 4 所以最大总和为 4
示例 2:
输入:nums = [6,2,6,5,1,2] 输出:9 解释:最优的分法为 (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9
排序就完了
class Solution {
public:
int arrayPairSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
int num=0;
for(int i=0;i<nums.size();i=i+2)
{
num+=min(nums[i],nums[i+1]);
}
return num;
}
};
---------------------------------------------------------------------------------------------------------------------------------
三、
难度中等324
给你一个整数数组 nums
,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]...
的顺序。
你可以假设所有输入数组都可以得到满足题目要求的结果。
示例 1:
输入:nums = [1,5,1,1,6,4] 输出:[1,6,1,5,1,4] 解释:[1,4,1,5,1,6] 同样是符合题目要求的结果,可以被判题程序接受。
示例 2:
输入:nums = [1,3,2,2,3,1] 输出:[2,3,1,3,1,2]
class Solution {
public:
void wiggleSort(vector<int>& nums) {
auto midptr = nums.begin() + nums.size() / 2;
nth_element(nums.begin(), midptr, nums.end());
int mid=*midptr;
int i=0,j=0,k=nums.size()-1;
while(j<k)//乱顺数组,若只有中位数位于中间,则将大于mid的数放在右边,反之;
{
if(nums[j]>mid)
{
swap(nums[j],nums[k]);
--k;
}
else if(nums[j]<mid)
{
swap(nums[i],nums[j]);
++i;
++j;
}
else
{
++j;
}
}
if(nums.size()%2)midptr++;
vector<int> tmp1(nums.begin(), midptr);
vector<int> tmp2(midptr, nums.end());
for(int i = 0; i < tmp1.size(); ++i){
nums[2 * i] = tmp1[tmp1.size() - 1 - i];
}
for(int i = 0; i < tmp2.size(); ++i){
nums[2 * i + 1] = tmp2[tmp2.size() - 1 - i];
}
}
};
几个问题:
1.nth_element()函数
在C++中,可以用STL的nth_element()函数进行快速选择,这一函数的效果是将数组中第n小的元素放在数组的第n个位置,同时保证其左侧元素不大于自身,右侧元素不小于自身。
2.使用三个参数i,j,k来控制数组,第一个if:nums[j]大于mid,则其一定得在右边,与nums[k]交换即可,则nums[k]一定大于0,而nums[j]交换过来的不一定,所以对j不变化;第二个if:nums[j]小于mid,交换i,j,使小于mid的数永远在左边。
3.快速选择算法:
void quickSelect(vector<int> &nums, int begin, int end, int n){
int t = nums[end - 1];
int i = begin, j = begin;
while(j < end){
if(nums[j] <= t){
swap(nums[i++], nums[j++]);
}
else{
++j;
}
}
if(i - 1 > n){
quickSelect(nums, begin, i - 1, n);
}
else if(i <= n){
quickSelect(nums, i, end, n);
}
}
虚地址方法(没搞懂之后学)
class Solution {
public:
void wiggleSort(vector<int>& nums) {
int n = nums.size();
// Find a median.
auto midptr = nums.begin() + n / 2;
nth_element(nums.begin(), midptr, nums.end());
int mid = *midptr;
// Index-rewiring.
#define A(i) nums[(1+2*(i)) % (n|1)]
// 3-way-partition-to-wiggly in O(n) time with O(1) space.
int i = 0, j = 0, k = n - 1;
while (j <= k) {
if (A(j) > mid)
swap(A(i++), A(j++));
else if (A(j) < mid)
swap(A(j), A(k--));
else
j++;
}
}
};
---------------------------------------------------------------------------------------------------------------------------------
四、
难度简单457
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 i
,都有一个胃口值 g[i]
,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j
,都有一个尺寸 s[j]
。如果 s[j] >= g[i]
,我们可以将这个饼干 j
分配给孩子 i
,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
示例 1:
输入: g = [1,2,3], s = [1,1] 输出: 1 解释: 你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。 虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。 所以你应该输出1。
示例 2:
输入: g = [1,2], s = [1,2,3] 输出: 2 解释: 你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。 你拥有的饼干数量和尺寸都足以让所有孩子满足。 所以你应该输出2.
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int n=0;
int m=0;
int count=0;
while(n<s.size()&&m<g.size())
{
if(s[n]>=g[m])
{
count++;
n++;
m++;
}
else if(s[n]<g[m])
{
n++;
}
}
return count;
}
};
---------------------------------------------------------------------------------------------------------------------------------
五、
难度简单21
给你一个整数数组 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
的数组是严格递增的一种特殊情况。
示例 1:
输入:nums = [1,1,1] 输出:3 解释:你可以进行如下操作: 1) 增加 nums[2] ,数组变为 [1,1,2] 。 2) 增加 nums[1] ,数组变为 [1,2,2] 。 3) 增加 nums[2] ,数组变为 [1,2,3] 。
示例 2:
输入:nums = [1,5,2,4,1] 输出:14
示例 3:
输入:nums = [8] 输出:0
class Solution {
public:
int minOperations(vector<int>& nums) {
if(nums.size()==1)return 0;
int key=nums[0];
int cishu=0;
for(int i=1;i<nums.size();i++)
{
if(nums[i]<key)
{
int t=key-nums[i]+1;
cishu+=t;
key=key+1;
}
else if(nums[i]>key)
{
key=nums[i];
}
else
{
cishu++;
key++;
}
}
return cishu;
}
};