数组拆分I,数组形式的整数加法,种花问题

数组拆分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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值