常见的数组问题

22 篇文章 0 订阅

1、给定一个含有n个元素的整型数组a,求a中所有元素的和。(要求采用递归的方式,一行代码)

  参考答案:

#include<stdio.h>

int sum(int* a,int n);

int main()
{
    int array[5] = {1,2,3,4,5};
    int summer;
    summer = sum(array,sizeof(array)/sizeof(array[0]));
    printf("sum %d\n",summer);

    return 0;
}

int sum(int* a,int n)
{
    return n == 0 ? 0 : sum(a,n-1) + a[n-1];
}
2、给定一个含有n个元素的整型数组a,找出其中的最大值和最小值

本题如果你能用分治法来求解的话,就比单纯的采用遍历法高一阶了

#include<stdio.h>

#define N 5

int get_minvalue(int* a,int n);
int get_maxvalue(int* a,int n);
int get_min_max(int* a,int n,int* min,int* max);

void MaxandMin(int *a, int l, int r, int* maxValue, int* minValue);

int main()
{
    int array[N] = {3,6,9,1,6};
    int min,max;

    min = get_minvalue(array,N);
    max = get_maxvalue(array,N);

    printf("min value %d,max value %d\n",min,max);

    get_min_max(array,N,&min,&max);
    printf("min value %d,max value %d\n",min,max);
    
    MaxandMin(array,0,N-1,&max,&min);
    printf("min value %d,max value %d\n",min,max);

    return 0;
}

int get_min_max(int* a,int n,int* min,int* max)
{
    int i;
    *min = *max = a[0];
    
    for(i = 1; i < n; i++)
    {
        if(*min > a[i]) *min = a[i];
        if(*max < a[i]) *max = a[i];
    }

    return 0;
}

int get_minvalue(int* a,int n)
{
    int minvalue = a[0];
    int i;
   
    for(i = 1; i < n; i++)
    {
        if(a[i] < minvalue) minvalue = a[i];
    }

    return minvalue;
}

int get_maxvalue(int* a,int n)
{
    int maxvalue = a[0];
    int i;
   
    for(i = 1; i < n; i++)
    {
        if(a[i] > maxvalue) maxvalue = a[i];
    }

    return maxvalue;
}

void MaxandMin(int *a, int l, int r, int* maxValue, int* minValue)
{ 
        if(l == r) 
        { 
                *maxValue = a[l] ; 
                *minValue = a[l] ; 
                return ; 
        } 
        if(l + 1 == r)
        { 
                if(a[l] >= a[r]) 
                { 
                        *maxValue = a[l] ; *minValue = a[r] ; 
                } 
                else { *maxValue = a[r] ; *minValue = a[l] ; } 
                return ; 
        } 
        int m = (l + r) / 2 ; 
        int lmax ; int lmin ; int rmax ; int rmin ;  
        MaxandMin(a, l, m, &lmax, &lmin); 
        MaxandMin(a, m + 1, r, &rmax, &rmin); 
        *maxValue = lmax > rmax ?lmax:rmax; 
        *minValue = lmin < rmin ?lmin:rmin;
}

3、给定一个含有n个元素的整型数组,求其最大值和次大值

       本以为和上面最大值和最小值的方法一样,不同之处只是取最大和次大的区别,但是在测试的时候遇到问题,比如对l == r的处理,如果相同则最大和次大是同一数,如下列的数组,有一组就会是lmax = lsec = 9;而9是最大的数,结果就是最大和次大都是9,所以须要解决这个问题,第一,如果只有一个数的数组,那么最大和次大都是同一数,这没有问题;第二,如果数组大小不是1,那么如果遇到 l == r的情况时,我们就设定为int的最小值INT_MIN,这样就可以解决上面遇到的问题了。

#include<stdio.h>
#include<limits.h>
 #define N 5
//#define N 1

int get_max_sec(int* a,int l,int r,int* max,int* sec);

int main()
{
    int array[N] = {3,6,9,1,5};
    //int array[N] = {3};
    int max,sec;

    get_max_sec(array,0,N-1,&max,&sec);
    printf("max value %d,second value %d\n",max,sec);
    
    return 0;
}

int get_max_sec(int* a,int l,int r,int* max,int* sec)
{
    if(l == r)
    {
        if(r == 0)
        {
            *max = *sec = a[l];
        }
        else
        {
            *max = a[l];
            *sec = INT_MIN;
        }
        return 0;
    }  
    
    if(l + 1 == r)
    {
        if(a[l] >= a[r])
        {
            *max = a[l];
            *sec = a[r];
        }
        else
        {
            *max = a[r];
            *sec = a[l];
        }
        //*max = a[l] >= a[r] ? a[l] : a[r];
        //*sec = a[l] >= a[r] ? a[r] : a[l];
        return 0;
    }

    int mid = (l + r)/2;
    int lmax,lsec,rmax,rsec;
    get_max_sec(a,l,mid,&lmax,&lsec);
    get_max_sec(a,mid + 1,r,&rmax,&rsec);

printf("lmax %d lsec %d rmax %d rsec %d\n",lmax,lsec,rmax,rsec);

    if(lmax > rmax)
    {
        *max = lmax;
        *sec = lsec > rmax ? lsec : rmax; 
    }
    else if(lmax < rmax)
    {
        *max = rmax;
        *sec = rsec > lmax ? rsec : lmax;
    }

    return 0;
}


4、求数组中出现次数超过一半的元素(另一种说法是:给定一个n个整型元素的数组a,其中有一个元素出现次数超过n / 2,求这个元素。)

      我们可以想象一下,n个整形元素的数组,超过n/2个元素是相同的,无论如果排序,至少有3个元素是相邻的。网上提供了两种方法,一,先排序,取中间元素即可,如果你能选择一些牛叉的排序方法,你可以加分;二,计数,从前往后,如果值相同则+1,否则-1,如果计数小于0,则清空,再开始,直到最后,剩下的那个就是要找的元素了。

排序的方法以后单独开个板块,这里只是看看第二种方法。

#include<stdio.h>

#define N 10

int find_data(int*a ,int n,int* data);

int main()
{
    int array[N] = {1,2,1,2,4,2,2,2,4,2};
    int data;

    find_data(array,N,&data);

    printf("the value is %d\n",data);
   
    return 0;
}

/* 计数的方法查找元素 */
int find_data(int* a,int n,int* data)
{
    int curr_value;
    int count;
    int i;

    curr_value = a[0];
    count = 1;

    for(i = 1; i < N;i++)
    {
        if(curr_value == a[i]) count++;
        else 
        {
            count--;
            if(count < 0)
            {
                curr_value = a[i];
                count = 1;
            }
        }
    }

    *data = curr_value;    

    return 0;
}

5、给定一个含有n个元素的整型数组,找出数组中的两个元素x和y使得abs(x - y)值最小(求数组中元素的最短距离)

     使两个数的绝对值最小,当然是先排序,然后看看那两个相邻元素之间的绝对值最小了

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>

#define N 5

int compare(const void* a,const void* b);
int find_abs_min(int* a,int n);

int main()
{
    int array[N] = {0,2,1,9,4};

    find_abs_min(array,N);

    return 0;
}

int compare(const void* a,const void* b)
{
    return *(int*)a - *(int*)b ;
}

int find_abs_min(int* a,int n)
{
    int i;
    int min_value,j,k;

    qsort(a,n,sizeof(int),compare);

    min_value = INT_MAX;
    j = k = 0;
    for(i = 0;i < n - 1;i++)
    {
        if(a[i+1] - a[i] < min_value)
        {
            min_value = a[i+1] - a[i];
            j = a[i+1];
            k = a[i];
        }
    }

    printf("min_value %d,%d - %d\n",min_value,j,k);

    return 0;
}

6、给定两个含有n个元素的有序(非降序)整型数组a和b,求出其共同元素

参考答案

#include<stdio.h>

#define N 5
int find_comm(int* a,int* b,int n);

int main()
{
    int a[N] = {0,1,2,3,4};
    int b[N] = {1,3,5,7,9};

    find_comm(a,b,N); 

    return 0;
}

int find_comm(int* a,int* b,int n)
{
    int i = 0, j = 0;
    while(i < n && j< n)
    {
        if(a[i] < b[j]) i++;
        else if(a[i] == b[j])
        {
            printf("comm value is %d\n",a[i]);
            i++;
            j++;
        }
        else j++;
    }
    return 0;
}

7、给定三个含有n个元素的整型数组a,b和c,求他们最小的共同元素
      下面的参考答案给出的是三个数组所有相同元素,其第一个就是最小的共同元素。

#include<stdio.h>

#define AN 5
#define BN 6
#define CN 4

int compare(const void* a,const void* b);
int find_min_comm(int* a,int* b,int* c,int an,int bn,int cn);

int main()
{
    int a[AN] = {2,3,6,4,7};
    int b[BN] = {3,7,9,2,1,5};
    int c[CN] = {1,3,5,2};

    find_min_comm(a,b,c,AN,BN,CN);

    return 0;
}


int compare(const void* a,const void* b)
{
    return *(int*)a - *(int*)b;
}

int find_min_comm(int* a,int* b,int* c,int an,int bn,int cn)
{
    int i,j,k;

    qsort(a,an,sizeof(int),compare);
    qsort(b,bn,sizeof(int),compare);
    qsort(c,cn,sizeof(int),compare);

    i = j = k = 0;
    while(i < an && j < bn && k < cn)
    {
        if(a[i] < b[j]) i++;
        else
        {
            if(b[j] > c[k]) k++;
            else if(b[j] < c[k]) j++;
            else
            {
                if(a[i] == b[j])
                {
                    printf("comm %d\n",a[i]);
                    //break;
                    i++;j++;k++;
                }
                else
                {
                    j++;k++;
                }

            }
        }

    }

    return 0;
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值