三道简单算法题(二)

简介:

1:试着用最少的比较次数去寻找数组中的最大值和最小值。

思路一:扫描数组两次,第一次等到最大值,第二次等到最小值。总共比较次数2N,这是大家都可以想到的。

思路二:定义两个变量存放最大值和最小值,将数组两两分组,两两进行比较,大的和最大值进行比较,小的和最小值比较,数组两两比较次数是N/2,分别与最大值和最小值比较的次数为N,总共比较次数1.5N。好久没写算法了,于是蛋疼得想实现一下。

复制代码
//1:试着用最少的比较次数去寻找数组中的最大值和最小值。 
void FindMaxMin(int *A,int size,int* Max,int* Min)
{ 
    int i=(size & 1)?1:0;
    *Max=*Min=A[0]; 
    for(;i<size;i=i+2)
    {
        if(A[i]>A[i+1])
        {
            if(A[i]>*Max) 
                *Max=A[i]; 
            if(A[i+1]<*Min) 
                *Min=A[i+1]; 
        }else{
            if(A[i+1]>*Max) 
                *Max=A[i+1]; 
            if(A[i]<*Min) 
                *Min=A[i]; 
        }
    }  
}

void FindMaxMinTest(){
    int A[9]={2,4,6,8,9,1,3,5,7};
    int Max=0;
    int Min=0;
    FindMaxMin(A,9,&Max,&Min);
    cout<<Max<<endl;
    cout<<Min<<endl;
}
复制代码

写完之后,发现这太简单了,不过瘾,于是又实现了两题,当然这三道题的思路都很早之前就看过。

2:给一个整数数组,求数组中重复出现次数大于数组总个数一半的数

按照抵消的思路,如果存在一个数出现的次数大于数组的一半,将这个数与其他不同的数进行一一抵消,最后剩下的必定就是这个数,然后再验证这个数是否是真的出现次数超过数组的一半,实现如下,以前也实现过,但是发现这次的实现和以前的实现出入较大,这是为什么呢?

复制代码
//2:给一个整数数组,求数组中重复出现次数大于数组总个数一半的数
int MoreThanHalf(int *A,int size)
{ 
    int num=A[0];
    int count=1;
    for(int i=1;i<size;i++)
    { 
        if(num==A[i])
        {
            count++;
        }else{
            count--;  
            if(count==0)
            { 
                num=A[i];
                count=1;
            }
        } 
    }
     
    count=0;
    for(int i=0;i<size;i++)
    {
        if(A[i]==num)
            count++;
    }  
    return count>(size/2)? num:-1;
}

void MoreThanHalfTest()
{
    int A[9]={ 1, 1,2, 1, 2, 2, 1, 2, 2 };
    cout<<MoreThanHalf( A,9);
}
复制代码

 

3:给一个很大的数组,里面有两个数只出现过一次,其他数都出现过两次,把这两个数找出来

按照异或运算的思路解题。假设这两个数分别为A,B;将数组的每个元素异或运算一次,得到这两个数的异或运算结果C,因为其他的数都是两两出现,异或运算的值为0,这个结果值C的二进制位中为1的位必只有A,B其中一个数有,因为异或运算就是不同的值才能得到1,相同的为0。即1&1=0;0&0=0;1&0=1。那么我们就可以随便从结果C中取出一个二进制位为1的位与其后面的0得到一个数,若结果C的二进制位后8位为00010100,那么我们就可以得到4(二进制100),然后将数组中的每一个与4进行异或运算,这样我们就能将数组分为两组,A,B就被分到不同的组,其他的数被分到那个组并不用管,因为经过异或运算之后的值都为0,将两组分别就行以后运算之后就能得到A,B的值了,其他的数都互相抵消了。

复制代码
//3:给一个很大的数组,里面有两个数只出现过一次,其他数都出现过两次,把这两个数找出来
void FindTwoNum(int* A,int size, int* first,int* second)
{
    int excVal=A[0];
    for(int i=1;i<size;i++)
    {
        excVal^=A[i];
    }
    int s1=1;
    int s2=excVal;
    while((s2&1)==0)
    {
        s2>>=1;
        s1<<=1;
    }
    *first=excVal;
    for(int i=0;i<size;i++)
    { 
        if(s1&A[i]) 
            *first^=A[i];
    }
    *second=excVal^*first;
}

void FindTwoNumTest()
{
    int A[12]={2,1,1,2,3,3,5,7,4,4,7,9};
    int first=0,second=0;
    FindTwoNum(A,12,&first,&second);
    cout<<first<<endl;
    cout<<second;
}
复制代码

三道简单算法题(一)



本文转自啊汉博客园博客,原文链接:http://www.cnblogs.com/hlxs/archive/2013/03/28/2986191.html

目录
相关文章
|
12月前
|
人工智能 算法
算法提高:组合数学| 容斥原理常见应用
容斥原理常见的问题如下。 (1) 篮球、羽毛球、网球三种运动,至少会一种的有22人,会篮球的有15人,会羽毛球的有17人,会网球的有12人,既会篮球又会羽毛球的有11人,既会羽毛球又会网球的有7人,既会篮球又会网球的有9人,那么三种运动都会的有多少人? (2) 《西游记》《三国演义》《红楼梦》三大名著,至少读过其中一本的有20人,读过《西游记》的有10人,读过《三国演义》的有12人,读过《红楼梦》的有15人,读过《西游记》《三国演义》的有8人,读过《三国演义》《红楼梦》的有9人,读过《西游记》《红楼梦》的有7人。问三本书全都读过的有多少人?
123 0
算法提高:组合数学| 容斥原理常见应用
|
11月前
|
算法 Java 测试技术
LeetCode 周赛上分之旅 #46 经典二分答案与质因数分解
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
53 0
LeetCode 周赛上分之旅 #46 经典二分答案与质因数分解
|
机器学习/深度学习 算法
算法提高:组合数学| 卡特兰数的实现
卡特兰数列是组合数学中在各种计数问题中常出现的数列,其前几项为1,1,2,5,14,42,132,429,1430,4862,16796,58786,208012…… 卡特兰数首先是由欧拉在计算对凸n边形的不同的对角三角形剖分的个数问题时得到的,即在一个凸n边形中,通过不相交于n边形内部的对角线,把n边形拆分成若干三角形,不同的拆分数用Hn表示,Hn即卡特兰数。
107 0
算法提高:组合数学| 卡特兰数的实现
三道好题分享
上课睡觉 - AcWing题库
72 0
|
机器学习/深度学习 算法 索引
算法步步为营(1)-两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那两个整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。可以按任意顺序返回答案。
74 0
|
存储 算法 vr&ar
算法步步为营(02)-两数之和
两个非空链表,表示两个非负整数。它们每位数字都是逆序存储,且每个节点只能存储一位数字。 将两个数相加,并以相同形式返回一个表示和的链表。除了数字 0 之外,这两个数都不会以 0 开头。
90 0
|
存储 算法
【趣学算法】贪心算法、海盗古董装船问题
贪心选择是指原问题的整体最优解可以通过一系列局部最优的选择得到,也就是先做出当前最优的选择,将原问题变为一个相似却规模更小的子问题,而后的每一步都是当前最优的选择。这种选择依赖于已做出的选择,但不依赖于未作出的选择。
|
算法 JavaScript
两种高阶排序+四道简单力扣题带你走近“分而治之”
两种高阶排序+四道简单力扣题带你走近“分而治之”
98 0
两种高阶排序+四道简单力扣题带你走近“分而治之”
|
算法 Python
简单算法
python 简单算法
58 0
|
算法
重温算法之加油站
有时候自己一直找不到突破口是因为自己把问题想困难了,其实有的问题很简单,需要不断的分解。无论怎么样,这也是自己思考后的产物
111 0
重温算法之加油站