剑指offer之数组出现次数超过一半的数字

1 问题

数组中有一个数字出现了次数超过数组长度的一半,请找出这个数字。

比如{1,2,3,2,2,2,5,4,2},我们知道这个数是2

 

 

 

 

2 分析

我们数组元素个数分为单数和双数

1)数组长度是单数的情况下

我们有5个元素,里面至少3个2,还有2个元素我们可能重复也可能不重复

我们可以定义一个计数为1,先用变量保存数组第一个数据,然后遍历数组,如果发现后面的数据和前面的数据不一样,我们计数自动减1,如果一样计量数自动加1,当计数为0的时候,我们变量保存数组后面的一个数,比如{2,1,1,2,2},第二个1和第一个2抵消了,我们变量保存了第三个元素,但是第四元素值2和第3元素值也抵消了,最后的值也就是我么需要的值,如果是有2个不重复的数据比如,{1,3,2,2,2},我们第一个元素和第二个元素的值抵消了,当计量等于0就保存数组下一个元素,然后计量数归1,也就是我们保存第三个元素,然后计量加1,到最后,计量大于1,保存的元素就是我们想要的结果。

 

2)数组长度是双数的情况下

比如6个元素,至少有4个元素一样,2个元素和这4个元素不一样,这2个元素可能重复也可能不重复,和上面的分析也一样,用一个计量和一个变量保存第一个数据,然后后面的元素和前一个元素不一样,我们计量数就自动加1,当计量等于0就保存数组下一个元素,然后计量数归1,最后计量数肯定大于1,然后我们最后保存变量也是我们想要的结果。

 

 

 

3 代码实现

#include <stdio.h>
#include <stdlib.h>/**检测这个数有没有超过数组元素一半值。*/
int checkMoreThanHalf(int *datas, int length, int number)
{if (datas == NULL || length <= 0){return -1;}int count = 0;for (int i = 0; i < length; ++i){if (number == datas[i])++count;}if (count * 2 > length)return 1;elsereturn -1;}/**获取超过数组元素一半值这个数*/
int getMoreThanHalf(int* datas, int length)
{if (NULL == datas || length <= 0)return 0;int result = datas[0];int times = 1;for (int i = 1; i < length; ++i){if (times == 0){result = datas[i];times = 1;continue;}if (datas[i] == result){++times;}else {--times;}}int check = checkMoreThanHalf(datas, length, result);if (check)return result;elsereturn -1;
}int main(void) 
{int a[] = {2, 1, 2, 3, 2};int moreNumber = getMoreThanHalf(a, sizeof(a) / sizeof(int));printf("moreNumber is %d\n", moreNumber);return 0;
}

 

 

 

4 运行结果

moreNumber is 2

 

 

 

5 另外思路

分析:我们知道剑指offer之partition算法 可以找出一个数据,进行把所有数据分为左边小于其中的一个值,右边的大于一个值,既然题目说了 有一个数字出现了次数超过数组长度的一半,如果数组是奇数个数的话,比如{1,2,3,2,2};我们知道如果排序后最中间的数字就是2,也就是我们的中位数,如果数组是偶数个数的话,比如{1,2,3,2,2,2};这里不能只有3个2,不然3个其他数和题目逻辑矛盾,所以至少是4个2,然后我么进行求这个数组的中位数还是2,所以现在题目演变成了,如果这个数据排序好了,我们求出中位数就行,也就是通过partition算法求出返回值为(数组长度 / 2)的值,然后我们再获取数组下表是值为 数组长度 / 2 的数组值就行。

 

 

 

6 代码实现

#include <iostream>
#include <vector>using namespace std;void swap(int* a, int* b)
{int temp = *a;*a = *b;*b = temp;
}void printVector(vector<int> v) 
{for (int i = 0; i < v.size(); ++i){std::cout << v[i] << "\t";}std::cout << std::endl;
}/**partition算法 记得如果这里是C++我们传递的是vector类型,我们记得要加引用,*不然改变不了数据,这里和java传递ArrayList不一样,ArrayList作为参数可以改变集合里面的值,*所以C++如果函数传递非基本数据类型,一半都是带引用的*/
int partitionOne(vector<int>& vector, int start, int end)
{if (start > end){std::cout << "vector is empty or start > end" << std::endl;return -1;}int pivot = vector[start];while (start < end){//我们先从尾巴开始while (start < end && pivot <= vector[end]){--end;}//这里用的数组赋值,而不是直接用swap交换函数,那么下面的2步也是用数组赋值,而不是用swap交换函数vector[start] = vector[end];while (start < end && pivot >= vector[start]){++start;}vector[end] = vector[start];}//std:cout << "start is " << start << "end is " << end << std::endl;vector[start] = pivot;//printVector(vector);return start;
}void getMoreThanHalf(vector<int>& vector)
{if (vector.size() <= 0){std::cout << "vector.size is <= 0" << std::endl;return;}int start = 0;int end = vector.size() - 1;int middle = vector.size() / 2;int index = partitionOne(vector, start, end);printVector(vector);while (index != middle){if (index > middle){end = index - 1;index = partitionOne(vector, start, end);}else{start = index + 1;index = partitionOne(vector, start, end);}}
}int main()
{vector<int> v2;v2.push_back(2);v2.push_back(1);v2.push_back(2);v2.push_back(3);v2.push_back(2);v2.push_back(-1);v2.push_back(2);printVector(v2);int a[] = {2, 1, 2, 3, 2};getMoreThanHalf(v2);std::cout << "value is " << v2[v2.size() / 2] << std::endl;return 0;
}

 

 

 

7 运行结果

2	1	2	3	2	-1	2	
-1	1	2	2	2	3	2	
value is 2

 

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

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

相关文章

C#多线程调试

概要这篇文章主要分享多线程部分调试技巧&#xff0c;在日常的开发工作中会经常遇到多线程调试的需要。在我们调试的过程中会出现断点的焦点在多个线程之间“反复横跳”根本无法集中跟踪某一个线程的操作链路。那么今天我们来看看如何调试操作。如果有其它需要的可以参考下面微…

最速下降法(梯度下降法)

最速下降法的影子在机器学习中正是无处不在&#xff0c;它简单实用。 一、表示 在最速下降法中&#xff0c;对权值向量w的连续调整是在最速下降的方向上&#xff0c;即它是与梯度向量方向相反的&#xff0c;梯度向量记为&#xff08;1&#xff09;&#xff0c;简记&#xff08;…

游戏服务器销售额,游戏服务器销售一个月

游戏服务器销售一个月 内容精选换一换应用容器化改造有三种方式&#xff0c;您可单击这里查看。本教程以某游戏为例&#xff0c;将该游戏进行微服务的架构改造&#xff0c;再进行容器化。本教程不对改造细节做深度讲解&#xff0c;仅讲解大致的建议。如需要详细了解容器化改造的…

使用AppCompat项目模版

2019独角兽企业重金招聘Python工程师标准>>> 使用AppCompat项目模版 从Android API 22开始&#xff0c;谷歌推荐使用AppCompatActivity来构建带标题栏的App&#xff0c;而不是原有的ActionBarActivity。如果用户想要使用AppCompatActivity&#xff0c;可以使用Xamar…

python3 最基本且简单的实现组合设计模式

组合模式是把一个类别归为一个整体&#xff0c;并且组织多个整体之间的关系&#xff0c;使用通过树形结构来描述所有整体。 一般的编写方式为一个类别对象下添加多个该对象的元素&#xff0c;该对象又为其它对象下的元素。简单来说就是一个学校有一个总部&#xff0c;总部下有…

SQL Server 2008 阻止保存要求重新创建表的更改问题

习惯了使用SQL Server 2005进行数据库系统开发,为了赶上潮流的发展,最近在使用SQL 2008数据库,本来建好了一个表,后面需要对表的设计做些修改(比如字段长度的修改,忘记了设置主键等等),结果弹出错误提示,说什么“组织保存要求重新创建表的更改”,如下所示: 解决办法…

华为手机像素密度排行_华为手机也分三六九等,3款几乎“0差评”,支持5G价格良心...

随着9月15日美国对华为禁令的生效&#xff0c;台积电、三星等都无法再为华为供货。目前&#xff0c;华为芯片库存有限&#xff0c;可以说是用一片少一片&#xff0c;十分珍贵。因此&#xff0c;许多消费者都希望能在华为芯片用完之前&#xff0c;换一部新机。不过&#xff0c;华…

$geoNear

怎么使用mongoose的geoNear 2014-11-26 15:05:20| 分类&#xff1a; mongodb | 标签&#xff1a;mongoose |举报|字号 订阅 下载LOFTER我的照片书 |起因 在开发的时候碰到一个情况&#xff0c;数据源有100个景点&#xff0c;需要对给出的一个点&#xff0c;求距离它最近的…

linux shell之删除当前文件夹不包含文件1和文件2的其他所有文件

1 问题 删除当前文件夹不包含文件1和文件2的其他所有文件&#xff0c;这个当前文件夹里面可以包含子文件夹&#xff0c;然后子文件夹里面也有文件1和文件2&#xff0c;但是这里的文件1和文件2也不应该被删除。 2 解决办法 可以用如下shell命令都行 find . -type f -not -name…

甲骨文宣布供应链管理云平台支持LogFire仓库管理系统

本文讲的是 :甲骨文宣布供应链管理云平台支持LogFire仓库管理系统 ,【IT168 资讯】甲骨文发布了一系列对其供应链管理产品的更新&#xff0c;并表示&#xff0c;云平台现在支持去年收购LogFire的仓库管理系统(WMS)。 ▲ Oracle将在最新版本的Oracle供应链管理(SCM)Cloud产品…

i5老是显示无服务器,为什么懂电脑的人选择买i5处理器,而不是i7,背后的真实原因?...

摘要&#xff1a;我们在选购电脑的时候经常会被五花八门的型号参数看的神魂颠倒&#xff0c;有很多朋友对cpu的理解也仅限于i7一定比i5好&#xff0c;i5一定比i3好的阶段。然而&#xff0c;对于很多懂电脑的人来说&#xff0c;选购电脑时&#xff0c;都不会买i7的CPU处理器&…

C# 对类型系统扩展性的改进

前言C# 对类型系统进行改进一直都没有停过&#xff0c;这是一个长期的过程。C# 8 之后则主要围绕扩展性方面进行各种改进&#xff0c;目前即将发布的 C# 11 中自然也包含该方面的进度。这些改进当然还没有做完&#xff0c;本文则介绍一下已经推出和即将推出的关于这方面改进的新…

python 实现装饰器设计模式

python 装饰器简单、基本的实现并不复杂。装饰器&#xff08;Decorators&#xff09;模式类似于继承&#xff0c;当你需要为某一个对象添加额外的动作、行为时&#xff0c;在不改变类的情况下可以使用装饰器。这篇文就当做一篇水文&#xff0c;本来不想写&#xff0c;因为这个专…

Excel抽奖小程序

今天分享一个用Excel制作的抽奖小程序。 如上图&#xff0c;制作一个抽奖小界面&#xff0c;滚动显示区域写入“INDIRECT("A"&RANDBETWEEN(2,13))”&#xff0c;按F9键不放&#xff0c;程序开始运行&#xff0c;松开F9键&#xff0c;抽奖完成。 函数解说&#x…

python导入函数模块 为什么会打印两次_5.1.2Python从模块导入函数

Posted by 撒得一地 on 2016年3月2日 in python教程国外稳定加速器推荐vypr |NordPython下模块导入函数&#xff0c;即把某件事作为另一件事导入&#xff0c;从模块导入函数的时候&#xff0c;可以使用&#xff1a;import somemodule或者from somemodule import somefunction或…

lz98n外接电源注意问题

当外接电源时&#xff0c;要将跳线帽拔掉&#xff0c;外接电源- 接12v和gnd 此时还得注意 l298n5v变成的使能输入 必须是单片机的io5v输入 而且单片机的gnd要和l298n的gnd链接 也就是来l298N的GND 要接两根线 一个是外部电源的- 还有就是单片机的gnd 特别注意 l298n的5v不…

剑指offer之partition算法

1 问题 partition 算法: 从无序数组中选出枢轴点 pivot&#xff0c;然后通过一趟扫描&#xff0c;以 pivot 为分界线将数组中其他元素分为两部分&#xff0c;使得左边部分的数小于等于枢轴&#xff0c;右边部分的数大于等于枢轴&#xff08;左部分或者右部分都可能为空&#x…

Vagrant搭建可移动的PHP开发环境

准备 开发所需工具&#xff1a; VagrantOneinstackVirtualboxVagrant box系统环境&#xff1a;macOS Sierra 10.12.5搭建系统&#xff1a;CentOS 7搭建环境&#xff1a;Oneinstack&#xff08;PHP以及Java环境&#xff09; 为啥不用docker&#xff1f;因为很多公司用的windows&…

让DIV中文字换行显示

让DIV中文字换行显示 1. <style>div{white-space:normal;word-break:break-all;word-wrap:break-word; }</style><div style" width:100px; border:1px solid red">I am a doibiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii</div> 未加css前效果&…

C# numericUpDown控件用法总结及注意事项

numericUpDown控件在使用的过程当中,有些用法会不太一样,下面做一总结。 1. 判断numericUpDown的value属性是否为空 使用过Numericupdown控件的童鞋初期应该都会碰到一个奇怪的问题,在删除了控件里的值之后,里面实际上还是有数据的,所以也没办法判断非空了。 这里我觉得是…