力扣-283周赛-第二题

给你一个整数数组 nums 和一个整数 k 。请你向 nums 中追加 k 个 未 出现在 nums 中的、互不相同 的 正 整数,并使结果数组的元素和 最小 。

返回追加到 nums 中的 k 个整数之和。

示例 1:

输入:nums = [1,4,25,10,25], k = 2
输出:5
解释:在该解法中,向数组中追加的两个互不相同且未出现的正整数是 2 和 3 。
nums 最终元素和为 1 + 4 + 25 + 10 + 25 + 2 + 3 = 70 ,这是所有情况中的最小值。
所以追加到数组中的两个整数之和是 2 + 3 = 5 ,所以返回 5 。
示例 2:

输入:nums = [5,6], k = 6
输出:25
解释:在该解法中,向数组中追加的两个互不相同且未出现的正整数是 1 、2 、3 、4 、7 和 8 。
nums 最终元素和为 5 + 6 + 1 + 2 + 3 + 4 + 7 + 8 = 36 ,这是所有情况中的最小值。
所以追加到数组中的两个整数之和是 1 + 2 + 3 + 4 + 7 + 8 = 25 ,所以返回 25 。
 

提示:

1 <= nums.length <= 105
1 <= nums[i], k <= 109

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/append-k-integers-with-minimal-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目思路:

先将原数组按降序排

其实看明白了题目就是用求和公式;

比如数组:nums = [5,6],插入个数:k = 6

就是要插入1--4和7,8;

1-4就等于Sn=(am+an)(n-m)/2 ==> (1+4)*4/2;

所以定义一个变量count记录am到an之间有几个;   count==(n-m);

定义一个变量 j 代表am,当然 j 从 1 开始; am = j;

你应该可以看出来 an=am+count-1; an=j+count-1;

所以本题的求和公式是 : Sn = (am+an)*count/2 ==> (j+j+count-1)*count/2

==>(2*j+count-1)*count/2;

有几个注意的点就是:

1.可能数组遍历完了,k>0,所以要返回时要多求一次和

2.可能数组还没遍历完,k==0,所以count要取一个最小值count=min(nums[i]-j,k);

void swap(int q[],int i,int j)
{
    int t= q[i];
    q[i] = q[j];
    q[j] = t;
}
void quickSort(int q[],int l,int r)
{
    if(l>=r) return ;
    int i=l-1,j=r+1;
    int x=q[l+r>>1];
    while(i<j)
    {
        do i++; while(q[i]<x);
        do j--; while(q[j]>x);
        
        if(i<j)
        {
            swap(q,i,j);
        }
    }
    quickSort(q,l,j);
    quickSort(q,j+1,r);
}
int min(int a,int b)
{
    return a>b? b:a;
}

long long minimalKSum(int* nums, int numsSize, int k){
    quickSort(nums,0,numsSize-1);
    long long int sum=0;
    long long int j=1;
    for(int i=0;i<numsSize&&k;i++)
    {
        if(j<nums[i])
        {
           int count=min(nums[i]-j,k);//因为k<(nums[i]-j)的个数,所以要取最小
           k-=count;
           sum+=(2*j+count-1)*count/2;//求和公式
        }
        j=nums[i]+1;
    } 
    return sum+(2*j+k-1)*k/2;//可能数组遍历完了,所以要返回时再求一次,反正k==0等于 sum+0
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值