zoukankan      html  css  js  c++  java
  • 三道简单算法题(二)

    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;
    }

    三道简单算法题(一)

  • 相关阅读:
    MySQL——sql语句处理时间——时间、字符串、时间戳互相转换
    MySQL——sql语句处理时间——日期加减天数
    Spring Boot——jpaProperties.getHibernateProperties()的使用
    Spring Boot——SpringBoot2+JPA+druid配置多数据源
    Spring Boot——log4j日志配置案例
    git命令——git 分支操作
    windows如何删除默认打开方式
    excel导出出现弹框
    笔记
    javascript中三个等号"==="是什么意思
  • 原文地址:https://www.cnblogs.com/hlxs/p/2986191.html
Copyright © 2011-2022 走看看