一个n位的数,去掉其中的k个数,使剩下的数最小

一个n位的数,去掉其中的k位,问怎样去使得留下来的(n-k)位数按原来的前后顺序组成的数最小

思路一:
分析:求一共n位,求其中的m位组成的数最小。那么这个m位的数,最高位应该在原数的最高位到第m位区间找,要不然就不能当第m位了。

比如一个数:8 4 7 9 6 3 5 2
n = 8, k = 3;
1.第一个数应在 8 —— 3 间(含8和3)选最小的,应为3
2.第二个数应在5——2 间(含5和2)选最小的,应为5
3.第三个数则为 2;
所以最小数为 352;

在比如 k = 4;
1.第一个数在 8——6 间选,应为4
2.第二应在 7——3 间选,应为3
其余同上。
最小为 4352;

注意:
在区间有多个最小值,取距离最大的,保证下一位数有足够大的查找空间。

图解链接

代码实现:

#include<stdio.h>
void Find_min(int a[],int beg,int fin,int a_len)
{
    int i;
    int minIndex;	//表示每个区间最小值的下标
    minIndex = beg;	//开始赋值为区间左边界
    for (i=beg;i<=fin;i++)		//遍历区间,寻找最小值
    {
        if (a[i]<a[minIndex])
            minIndex = i;
    }
    printf("%d",a[minIndex]);	//输出
    if (fin+1 < a_len)	//直到遍历整个数组
    Find_min(a,minIndex+1,fin+1,a_len);	//下个区间
    //下个区间的左边界为上个区间找到的最小值下标加 1 ;右边界为上个区间的右边界加1
}
int main()
{
    int a[] = {1,3,8,1,4,9,2,5};	//用数组保存数字
    int k;	// k 表示去的个数
    scanf("%d",&k);
    size_t size = sizeof(a)/sizeof(int);		//计算数组的长度
    Find_min(a,0,k,size);		//求每个区间的最小值函数
    return 0;
}

思路二:
分析:从前往后找,每次访问一位,比较该位前边的数,如果比该位大,果断干掉,直到干掉个数为k或访问到最后了。当然遍历到最后还没有干掉K个元素,说明剩下的已经为升序了,这样就在留下的数中取出前(n-k)个,整合成整数就是最小值。

比如:8 3 1 4 9 2 5
n = 7,k = 5;
i = 1 为访问元素下标,由于去掉一个元素,所以下标减 1 ;又因为要访问下一个元素,所以下标有得加 1 ;
而不用处理时,元素不往前移,所以下标不减只加 为 i+1;
1.访问 3,前边 8 大,去掉 8 为
3 1 4 9 2 5 (下一访问下标为 i = 1)
2.访问 1,前边 3 大,去掉 3 为
1 4 9 2 5 (下一访问下标为 i = 1)
3.访问 4,前边 1 小,不用处理 (下一访问下标为 i = 2)
4.访问 9,前边 4 小,不用处理 (下一访问下标为 i = 3)
5.访问 2,前边 9 大,去掉 9 为 (下一访问下标为 i = 3-1)
1 4 2 5
6.继续 特别注意:因为只知道2前面的数是升序,并不知道包含2是否升序访问 2,前边 4 大,去掉 4 为
1 2 5
所以结果为125

代码实现:

#include<stdio.h>
int main()
{
    int a[] = {1,1,6,2,4,3};
    int i = 1;
    size_t n;
    n = sizeof(a)/sizeof(int);
    int k = 2;
    while(k)		//只要没有干掉 k 个数,循环就得进行
    {
        if (a[i-1] > a[i])	//比较前后两个数的大小
        {
            for (int j = i;j < n;j++)	//数组前移
                a[j-1] = a[j];
            k--;		
            n--;		//数组个数减少
            if (i>1)	// i > 1 表示干掉的数前面至少有两个数,由于不知道干掉数后一个数与前面数的大小,所以的判断。这里参照上面例子更好理解 
            i--;
        }
        else
            i++;
    }
    for (i=0;i<n;i++)
        printf("%d",a[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43557810/article/details/87013651