算法系统学习-找第k小值(非等分分治)

简介: 该系列是基于有一定语言基础(C,C++,Java等等)和基本的数据结构基础进行的算法学习专栏,如果觉得有点吃力 😥 ,建议先了解前提知识再学习喔!本个专栏会将用更容易理解的表达去学习算法,如果在一些表述上存在问题还请各位多多指点

非等分二分法


现实中常见的应用就是寻找中值元素(中值是一个很有用的统计量,例如中间工资,中间年龄,中间重量等),因此经常会遇到在“一组数据中取第k小的值”。

按照以前的最好的排序算法的复杂性是O(nlogn),但我们可以利用二分法将复杂度降为O(n),可这个二分法不是简单典型的二分法分解成完全独立,相似的两个问题,因为在选出分解后第一组的第k小的数据和第二组的第k小的数据,不能保证这两个数据之一是原问题的解。


Case1:

求一组数的第二小的数

算法分析:

在用二等分法分解的两个子集中,无论只选取第二小数据或只选取最小的数据,合并处理后都有可能得不到原问题的解。但若在两个子集中都选取最小的两个值,那原问题中第二小的数据则一定在这四个数据中。由此,将问题转化成“求一组数中较小的两个数”后,二等分法分解就可将原问题“分解为原问题独立且相似的两个问题”。

这样,回溯合并的过程就是从两个子问题选出的共4个数中,选取出较小的两个数,直到回溯结束,就得到一组数中较小的两个数,从而得到了原问题的解。


算法设计:

float a[100];
main(){
    int n;
    float min2;
    cin>>n;
    for(i=0;i<n-1;i++){
    cin>>a[i];
    }
    min2=second(n);
    cout<<min2;
}
second(int n){
  float min2,min1;
    two(0,n-1,min2,min1);
    return min2;
}
two(int i,int j, float &fmin2,float &fmin1){
float lmin2,lmin1,rmin2,rmin1;
    int mid;
    if(i=j){
      fmin2=fmin1=a[i];
    }else if(i=j-1){
      if(a[i]<a[j]){
        fmin2=a[j];
        fmin1=a[i];
        }else{
        fmin2=a[i];
        fmin1=a[j];
        }
    }else{
    mid=(i+j)/2;
    two(i,mid,lmin2,lmin1);
    two(mid+1,j,rmin2,rmin1);
        if(lmin<rmin1){
          if(lmin2<rmin1){
                fmin1=lmin;
                fmin2=lmin2;
            }else{
            fmin1=lmin1;
            fmin2=rminl;
            }
        }else{
        if(rmin2<lmin1){
        fmin1=rmin1;
        fmin2=rmin2;
        }else{
        fmin1=rmin1;
        fmin2=lmin1;
        }
        }
    }
}


小结:

以上算法利用“分解为与原问题相似的两个子问题”的技巧,解决了一个个简单的排序问题。但对于选取第k小元素的问题,则从效率上是无法行得通的。难道就不能使用二分法解决这类问题?分治法中当然不仅仅包括二分法,也可以使用“非等份分解方法”的例子

Case2:

对于给定的n个元素的数组a【0:n-1】,要求从中找出第k小的元素,要求找到第k小的元素


问题分析:

选择问题的一个应用就是寻找中值元素,此时k=【n/2】。我们可以首先选取第一个数作为分界数据,将比它小的数据存在它的左边,将比它大的数据存储在右边,它存储在左右两个子集之间。(类似荷兰国旗问题)这样左右子集就是原问题分解后的独立子问题,再用同样的方法,解决这些子问题。知道每个子集只有一个数据,自然就有序了,也就完成了全部数据的排序工作。

可以通过改写快排算法,一趟排序分解出的左子集中元素个数left,可能有一下三种情况:

  1. nleft=k-1 ,则分界数据就是选择问题的答案
  2. nleft>k-1,则选择问题的答案继续在左子集中找,问题规模变小了
  3. nleft<k-1,则选择问题的答案继续在右子集中找,问题变成选择第k-nleft-1小的数,问题的规模也变小了

算法设计:

xzwt(int a[],int n,int k)  //返回a【0:n-1】中第k小的元素
{    if(k< 1|| k>n){
error();
}
 return select(a,0,n-1,k);
 }
select (int a[],int left,int right,int k){
//在a【left:right】中选择第k小的元素
    if(left >=right){
    return a[left];
    }
    int i=left;//从左至右的指针
    j=right+1;//从右至左的指针
    int pivot =a[left];
    while(1){
      do{
            //在左侧寻找>=pivot的元素
        i=i+1;
        }while(a[i]<pivot);
        do{
        j=j-1;
        }while(a[j]>pivot);//在右侧寻找<=pivot的元素
        if(i>=j){
        break;//未发现交换对象
        }
       Swap(a[i],a[j]);
    }
    if(j-left+1=k){
    return pivot;
    }
    a[left]=a[j];//设置pivot
    a[j]=pivot;
    if(j-left+1<k){   。//对一个段进行递归调用
    return select(a,j+1,right,k-j-1+left);
    }else{
    return select(a,left,j-1,k);
    }
}



目录
相关文章
|
25天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
数据结构与算法系列学习之串的定义和基本操作、串的储存结构、基本操作的实现、朴素模式匹配算法、KMP算法等代码举例及图解说明;【含常见的报错问题及其对应的解决方法】你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
|
12天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
43 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
12天前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
52 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
16天前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
32 2
|
18天前
|
机器学习/深度学习 算法 5G
基于MIMO系统的SDR-AltMin混合预编码算法matlab性能仿真
基于MIMO系统的SDR-AltMin混合预编码算法通过结合半定松弛和交替最小化技术,优化大规模MIMO系统的预编码矩阵,提高信号质量。Matlab 2022a仿真结果显示,该算法能有效提升系统性能并降低计算复杂度。核心程序包括预编码和接收矩阵的设计,以及不同信噪比下的性能评估。
36 3
|
21天前
|
机器学习/深度学习 人工智能 自然语言处理
【EMNLP2024】基于多轮课程学习的大语言模型蒸馏算法 TAPIR
阿里云人工智能平台 PAI 与复旦大学王鹏教授团队合作,在自然语言处理顶级会议 EMNLP 2024 上发表论文《Distilling Instruction-following Abilities of Large Language Models with Task-aware Curriculum Planning》。
|
25天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习(8)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
25天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
25天前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
25天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
下一篇
无影云桌面