分治法——找众数

分治法——找众数

要求:

寻找整数数组的众数,如果存在多个众数,则返回权值最小的那个


第一步:

要利用分治法找众数,首先就先要使数组有序。这里,我们用C语言库中的qsort进行快排:

qsort(nums, numsSize, sizeof(int), cmp_int);
//nums——给定数组
//numsSize——数组大小
//cmp_int——qsort要用到的函数指针

第二步:

开始编写分治算法,寻找众数。

函数声明:

void Find_Mode(int* nums, int begin, int end)

为了方便,我们先定义两个全局变量mode_countmode_index来记录众数出现的次数和下标

int mode_count = 0;	//记录众数出现的次数
int mode_index = 0;	//记录下标

我们以下面的有序数组为例:

在这里插入图片描述

  • 首先假设众数为数组中间的数,记其下标为mode

    int left = begin;
    int right = end;
    int mode = (right - left) / 2 + left;	//为防止整形移除,故不采用(right + left)/2的写法
    
  • 然后,移动leftright,确定有多少个值为nums[mode]的元素:

    while (left < right && nums[left] != nums[mode])left++;
    while (left < right && nums[right] != nums[mode])right--;//这样,值为nums[mode]的元素个数为(right - left + 1)
    

    在这里插入图片描述

  • 当确定好nums[mode]的个数count后,就需要比较[begin, left - 1][right + 1, end]这两个区间的和count的大小

    • 如果[begin, left - 1]区间的大小大于或等于count就说明该区间内可能出现出现次数更多的或者权值更小的众数。因此要继续进行递归分治
    • 对于区间[right + 1, end]同理。
    if (left - begin >= right - left + 1)Find_Mode(nums, begin, left - 1);if (end - right >= right - left + 1)Find_Mode(nums, right + 1, end);
    
  • 如果上面两个if语句没有执行,那就说明nums[mode]出现的次数count就是最大的,那就需要和mode_count(众数出现的次数)进行比较

    • 如果count == mode_count。那就比较nums[mode]nums[mode_index]的权值,并将众数更新为权值较小的那个,并更新mode_index
    • 如果count > mode_count。那就直接让众数为nums[mode],更新mode_countmode_index
    • 如果count < mode_cout。就不做任何修改
    //right - left + 1即上文所说的count
    if (mode_count <= right - left + 1)
    {//如果二者相等,就取权值较小的if (mode_count == right - left + 1)mode_index = nums[mode] < nums[mode_index] ? mode : mode_index;else{mode_index = mode;mode_count = right - left + 1;}
    }
    
  • 函数整体即为:

    int mode_count = 0;	//记录众数出现的次数
    int mode_index = 0;	//记录下标void Find_Mode(int* nums, int begin, int end)
    {int left = begin;int right = end;int mode = (right - left) / 2 + left;//移动做右指针,寻找nums[mode](假设的众数)的出现次数while (left < right && nums[left] != nums[mode])left++;while (left < right && nums[right] != nums[mode])right--;//如果左右区间的长度大于或者等于nums[mode](假设的众数)的出现次数//那就进行分治递归if (left - begin >= right - left + 1)Find_Mode(nums, begin, left - 1);if (end - right >= right - left + 1)Find_Mode(nums, right + 1, end);//更新众数if (mode_count <= right - left + 1){//如果二者相等,就取权值较小的if (mode_count == right - left + 1)mode_index = nums[mode] < nums[mode_index] ? mode : mode_index;else{mode_index = mode;mode_count = right - left + 1;}}
    }
    

整体代码:

#include <stdio.h>
#include <stdlib.h>int mode_count = 0;	//记录众数出现的次数
int mode_index = 0;	//记录下标void Find_Mode(int* nums, int begin, int end)
{int left = begin;int right = end;int mode = (right - left) / 2 + left;//移动做右指针,寻找nums[mode](假设的众数)的出现次数while (left < right && nums[left] != nums[mode])left++;while (left < right && nums[right] != nums[mode])right--;//如果左右区间的长度大于或者等于nums[mode](假设的众数)的出现次数//那就进行分治递归if (left - begin >= right - left + 1)Find_Mode(nums, begin, left - 1);if (end - right >= right - left + 1)Find_Mode(nums, right + 1, end);//更新众数if (mode_count <= right - left + 1){//如果二者相等,就取权值较小的if (mode_count == right - left + 1)mode_index = nums[mode] < nums[mode_index] ? mode : mode_index;else{mode_index = mode;mode_count = right - left + 1;}}
}//qsort需要的函数
int cmp_int(void const* num1, void const* num2)
{return *(int*)num1 - *(int*)num2;
}int main()
{int nums[] = { 10, 4, 2, 10, 5, 8, 9, 5, 6, 1, 4, 7, 2, 1, 7, 4, 3, 1, 7, 2 };int numsSize = sizeof(nums) / sizeof(int);qsort(nums, numsSize, sizeof(int), cmp_int);	//利用快速排序排序数组,是数组升序排列Find_Mode(nums, 0, numsSize - 1);	//找众数printf("众数为:%d\n", nums[mode_index]);return 0;
}

注:本题已通过牛客网[编程题]众数验证正确性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/161850.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flink的安装与使用(ubuntu)

组件版本 虚拟机&#xff1a;ubuntu-20.04.6-live-server-amd64.iso flink&#xff1a;flink-1.18.0-bin-scala_2.12.tgz jdk&#xff1a;jdk-8u291-linux-x64.tar flink 下载 1、官网&#xff1a;https://flink.apache.org/downloads/ 2、清华镜像&#xff1a;https://mirr…

ICP学习记录

1. 流程图 ICP&#xff08;一&#xff09;原理详解_icp原理-CSDN博客 ICP算法详解——我见过最清晰的解释-CSDN博客 ICP算法理解-CSDN博客 ICP知识点梳理笔记_icp非凸_KalutSirocco的博客-CSDN博客 【精选】【图像配准】点云配准ICP算法介绍&#xff1a;基础流程、ICP算法…

基于SSM的社区智慧养老监护管理平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

opencv复习(简短的一次印象记录)

2-高斯与中值滤波_哔哩哔哩_bilibili 1、均值滤波 2、高斯滤波 3、中值滤波 4、腐蚀操作 卷积核不都是255就腐蚀掉 5、膨胀操作 6、开运算 先腐蚀再膨胀 7、闭运算 先膨胀再腐蚀 8、礼帽 原始数据-开运算结果 9、黑帽 闭运算结果-原始数据 10、Sobel算子 左-右&#x…

【工具】Github统计代码行数工具推荐(VScode插件、兼容任何平台、不用下载安装包)

需求&#xff1a; 1&#xff09;被要求统计代码行数&#xff1b; 2&#xff09;不想打开Linux&#xff0c;懒得下载Windows版本GitStats&#xff1b; 3&#xff09;打开了Linux但也不记得find命令行怎么用&#xff1b; 4&#xff09;打开了Linux&#xff0c;装好了Gitstats但自…

解决gtihub访问不到的

解决gtihub访问不到的 小编一开始也是找不到git但是通过查询资料&#xff0c;最终也是找到了解决方式 据说git的ip地址通常会变化的&#xff0c;可以通过地址查询网站查询到git当前的ip https://sites.ipaddress.com/github.com/在输入框中github.com&#xff0c;然后搜索 在…

Linux笔记-对/dev/vda1和/dev/vda2的理解

首先是这张图&#xff1a; 对于&#xff1a; /dev/vda1和/dev/vda2 可以知道&#xff0c;这个机器是在虚拟机上的&#xff0c;从设备描述中可以看到&#xff0c;与IO有关。 问下ChatGPT 问&#xff1a;linux上 /dev/vda1 和 /dev/vda2是干嘛的 答&#xff1a; /dev/vda1和…

MATLAB和西门子SMART PLC UDP通信

MATLAB和SMART PLC的OPC通信请参考下面文章链接,这里不再赘述: MATLAB和西门子SMART PLC OPC通信-CSDN博客文章浏览阅读661次,点赞26次,收藏2次。西门子S7-200SMART PLC OPC软件的下载和使用,请查看下面文章Smart 200PLC PC Access SMART OPC通信_基于pc access smart的o…

制造行业数字化运维破局之道

项目背景 某大型汽车制造集团&#xff0c;致力于通过数字化、智能化运营手段为用户提升提供高品质的汽车产品和服务。IT部门不仅为内外部持续提供服务&#xff0c;同时为业务运营与核心系统运行提供重要支撑。数字化运维作为数字化转型的核心基础&#xff0c;不但要保障数据安…

使用 curator 连接 zookeeper 集群 Invalid config event received

dubbo整合zookeeper 如图&#xff0c;错误日志 2023-11-04 21:16:18.699 ERROR 7459 [main-EventThread] org.apache.curator.framework.imps.EnsembleTracker Caller0 at org.apache.curator.framework.imps.EnsembleTracker.processConfigData(EnsembleTracker.java…

Redis之Java操作Redis的使用

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《Redis实战开发》。&#x1f3af;&#x1f3af; …

【算法|二分查找No.4】leetcode 852. 山脉数组的峰顶索引

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…