【机试备考】Day5-查找第k小数

题目

牛客网-查找第k小数
查找一个数组的第K小的数,注意同样大小算一样大。 如 2 1 3 4 5 2 第三小数为3。
在这里插入图片描述

题解1

条件反射想到了快排,如果数组没有重复元素的话,直接快排然后判断枢轴元素是不是第k个就好了,王道书上就有例题

但是这道题是有重复元素的,需要去重才能找到真正第k小而不是排在第k位的

到这里还没完,还有一个问题是排序和去重应该先做哪一步?答案是应该先排序再去重,目的是降低时间复杂度或者空间复杂度,因为排序之后重复元素必然是相邻的,因此采用有序数组去重的方法即可,时间复杂度只需O(n)(王道上有原题)

无序 数组去重的方法需要利用辅助数组,代码如下:

/*无序数组去重*/
int main()
{
    /*输入*/
    int n,a[100];
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    int temp[100];

    /*去重*/
    int m=0;//记录temp中元素个数
    for(int i=0;i<n;i++)
    {
        int j=0;
        for(;j<m;j++)
        {
            if(a[i]==temp[j])
                break;
        }
        //到头了都没找到和a[i]相等的元素
        //说明a[i]不是重复元素
        //把a[i]加入temp里
        if(j==m)
        {
            temp[m++]=a[i];
        }
    }
    //输出
    for(int i=0;i<m;i++)
        cout<<temp[i]<<" ";
}

 
所以如果硬要先去重再排序的话,代码长这样:

#include<iostream>
#include<cstring>
using namespace std;
// 去重,采用辅助数组
int del(int *a,int n)
{
    int temp[1001];
    int m=0;//记录temp中元素个数
    for(int i=0;i<n;i++)
    {
        int j=0;
        for(;j<m;j++)
        {
            if(a[i]==temp[j])
                break;
        }
        //到头了都没找到和a[i]相等的元素
        //说明a[i]不是重复元素
        //把a[i]加入temp里
        if(j==m)
        {
            temp[m++]=a[i];
        }
    }
    memcpy(a,temp,sizeof(temp));//数组赋值的方法,注意一定不能直接赋值
    return m;
}
// 快排找第k小(王道上有原题)
int quickSort(int low,int high,int k,int *a)
{
    int alow=low;
    int ahigh=high;
    int pivot=a[low];
    while(low<high)
    {
        while(low<high&&a[high]>=pivot)
            high--;
        a[low]=a[high];
        while(low<high&&a[low]<=pivot)
            low++;
        a[high]=a[low];
    }
    a[low]=pivot;
    //下标为low的元素其实是第(low+1)个
    if(low==k-1)
        return pivot;
    else if(low>k-1)
        return quickSort(alow, low-1, k,a);
    else
        return quickSort(low+1, ahigh, k, a);
}

int main()
{
    int n,k,a[1001];
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
            cin>>a[i];
        cin>>k;
        n=del(a,n);//去重,返回新的数组的元素个数
        int res=quickSort(0,n-1,k,a);//快排找第k小
        cout<<res;
    }
}

改了好多遍才过的。。。还是太久没打代码生疏了,有的用法都忘记了
在这里插入图片描述
 

题解2

当然用库函数更简单了,但是感觉就没有练习的必要了,代码如下:大致思想是先排序(sort函数)后去重(unique函数),返回第k个元素

#include<iostream>
#include <algorithm>
using namespace std;
int main()
{
    int n,k,a[1001];
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
            cin>>a[i];
        cin>>k;

        /*sort+unique几乎可以算是数组去重的一个模板了,用的蛮多的,应该记下来*/
        sort(a,a+n);//排序
        unique(a,a+n);//去重
        
        cout<<a[k-1];//注意第k个元素的下标是k-1
    }
}

提交了几次平均时间和内存跟题解1也差不多。。。

这篇鸽了三天,主要是自己太菜了,这个代码改了好多遍都没过,还有最近课设+毕设比较忙,老把代码拖到最后做不完,现在稍微轻松一点了,一定争取赶上进度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值