数组拆分I
给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), …, (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大。
示例 1:输入: [1,4,3,2]输出: 4
解释: n 等于 2, 最大总和为 4 = min(1, 2) + min(3, 4).
提示:
n 是正整数,范围在 [1, 10000].
数组中的元素范围在 [-10000, 10000].
这里我们知道,若要使得两两分组后的每组最小值相加得到结果最大,我们就必须用最小的和其次的结合,这样损耗最小,所以,先使用快速排序将数组排为升序数组,(如果使用冒泡排序在数组很大时运算量将是一个天文数字)然后取奇数位即可:
int arrayPairSum(int* nums, int numsSize)
{
int i = 0, j = 0, flag = 0, result = 0;
for (i = 1; i<numsSize ; i++)
{
flag = nums[i];
j = i - 1;
while (j >= 0 && nums[j]>flag)
{
nums[j + 1] = nums[j];
j--;
}
nums[j+1] = flag;
}
for (i = 0; i<numsSize; i += 2)
{
result += nums[i];
}
return result;
}
数组形式的整数加法
对于非负整数 X 而言,X 的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231,那么其数组形式为 [1,2,3,1]。
给定非负整数 X 的数组形式 A,返回整数 X+K 的数组形式。
示例 1:输入:A = [1,2,0,0], K = 34输出:[1,2,3,4]解释:1200 + 34 = 1234
示例 2:输入:A = [2,7,4], K = 181输出:[4,5,5]解释:274 + 181 = 455
示例 3:输入:A = [2,1,5], K = 806输出:[1,0,2,1]解释:215 + 806 = 1021
示例 4:输入:A = [9,9,9,9,9,9,9,9,9,9], K = 1输出:[1,0,0,0,0,0,0,0,0,0,0]
解释:9999999999 + 1 = 10000000000
笔者在这里的思路是,先将K用动态内存分派转化为数组,然后比较与A数组那个更长,短的那一方先加到长的这一方来,然后对加后的数组从最后一位向前,遇十进一,到第一个元素时,如果依然大于9,则重新开辟一块更大的空间,将这一位也进行进位操作:
int* addToArrayForm(int* A, int ASize, int K, int* returnSize){
*returnSize = ASize;
if (K == 0){
return A;
}
int count = 0;
int yu = K, yu_copy = yu,ASize_copy = ASize;
while (yu){
count++;
yu /= 10;
}
int* tpr = (int*)malloc(sizeof(int) * count);
int count_copy = count;
while (yu_copy){
tpr[count_copy-1] = yu_copy % 10;
yu_copy /= 10;
count_copy--;
}
if (count <= ASize){
count_copy = count;
int i = ASize-1;
while (i){
if (count > 0){
A[i] += tpr[--count];
}
if (A[i] > 9){
A[i] -= 10;
A[i - 1] += 1;
}
i--;
}
if (count_copy==ASize){
A[0] += tpr[0];
}
if (A[0]>9){
*returnSize = ASize + 1;
int*tpr1 = (int*)malloc(sizeof(int)*(ASize+1));
for (i = 0; i<ASize; i++){
tpr1[i + 1] = A[i];
}
tpr1[0] = 1;
tpr1[1] -= 10;
return tpr1;
}
else{
return A;
}
}
else{
int i = count-1;
*returnSize = count;
while (i){
if (ASize_copy>0){
tpr[i] += A[--ASize_copy];
}
if (tpr[i] > 9){
tpr[i] -= 10;
tpr[i - 1] += 1;
}
i--;
}
if (tpr[0]>9){
*returnSize = count + 1;
int*tpr1 = (int*)malloc(sizeof(int)*(count + 1));
for (i = 0; i<count; i++){
tpr1[i + 1] = tpr[i];
}
tpr1[0] = 1;
tpr1[1] -= 10;
return tpr1;
}
else{
return tpr;
}
}
}
种花问题
假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。
示例 1:输入: flowerbed = [1,0,0,0,1], n = 1输出: True
示例 2:输入: flowerbed = [1,0,0,0,1], n = 2输出: False
注意:
数组内已种好的花不会违反种植规则。
输入的数组长度范围为 [1, 20000]。
n 是非负整数,且不会超过输入数组的大小。
我们从题中明白前一个与后一个都为空时我们才能种花,所以我们在查看此地能否种花如果是空地,再前后一检查,如果可以种标记一下即可(第一个与最后一个位置只需检查前或后即可),被标记过的地方就不可以当空地来看待了,一般情况下,只要可种数大于等于要求种的数量,返回结果即为真,这里还有一个特殊情况:如果要种的花数为0,则任何条件下都为真:
int canPlaceFlowers(int* flowerbed, int flowerbedSize, int n)
{
int i =0;
if(flowerbedSize==1)
{
if(n==1)
{return !flowerbed[0];}
else
return 1;
}
if(flowerbed[1]==0&&flowerbed[0]==0)
{
flowerbed[0] =2;
n--;
}
for(i =1;i<flowerbedSize-1;i++)
{
if(flowerbed[i]==0)
{
if(flowerbed[i+1]==0 && flowerbed[i-1]==flowerbed[i+1])
{
flowerbed[i] = 2;
n--;
}
}
}
if(flowerbed[flowerbedSize-2]==0&&flowerbed[flowerbedSize-1]==0)
{
n--;
}
if(!(n>0))
{
return 1;
}
return 0;
}