[C][Leetcode]455. 分发饼干

目录

【题目描述】

【解题思路】

【代码一:冒泡排序(超时了)】

【代码二:堆排序】

【代码三:归并排序】

【代码四:快速排序】


【题目描述】

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

 
示例 1:

输入: g = [1,2,3], s = [1,1]
输出: 1

解释: 
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。

【解题思路】

胃口最小的孩子最容易满足,若一块饼干同时可以满足胃口较大的孩子和较小的孩子,优先将其分给胃口小的孩子。

先将胃口数组和饼干尺寸数组分别排序(至少花费O(nlogn)的时间),然后比较最小的胃口和最小的饼干。若可以满足,把这块饼干给当前胃口最小的孩子;若不能满足,这块饼干也无法满足剩下的任一孩子,所以换为次小的饼干。

【代码一:冒泡排序(超时了)】

时间复杂度O(N^2)

void bubblesort(int* a,int asize){
    int i,j;
    int swap;
    int tmp;
    do{
        swap=0;   
        for(i=0;i<asize;i++){
            for(j=0;j<asize-i-1;j++){
                if(a[j+1]<a[j]){
                    tmp=a[j];
                    a[j]=a[j+1];
                    a[j+1]=tmp;
                    swap=1;  
                }
            }
        }
     }while(swap);
}

int findContentChildren(int* g, int gSize, int* s, int sSize){
   
    int i=0;
    int j=0;
    int cnt=0;
    bubblesort(g,gSize);
    bubblesort(s,sSize);

    if(sSize==0 || gSize==0 || g[0]>s[sSize-1]) return 0;
    
    while(i<gSize && j<sSize){
        if(g[i]<=s[j]){
            cnt++;
            i++;
            j++;
        }else if(g[i]>s[j]) j++;

    }


    return cnt;
}

【代码二:堆排序】

时间复杂度O(NlogN)

void Adjust(int *a,int now,int asize){//将数组a中的now调整为最大堆
    int tmp;
    tmp=a[now];
    int p;
    int i;
    for(i=2*now;i<=asize;i*=2){
        if(i<asize && a[i+1]>a[i]) i++;
        if(tmp>=a[i]) break;
        else{
            a[now]=a[i];
            now=i;
        }
        a[now]=tmp;
    }
}

void buildmaxHeap(int* a,int asize){//建立最大堆
    int i;
    for(i=asize/2;i>0;i--){
        Adjust(a,i,asize);        
    }    
}

void Hsort(int* a,int asize){//对最大堆进行堆排序
    int i;
    int tmp;
    for(i=asize;i>1;i--){
        tmp=a[1];
        a[1]=a[i];
        a[i]=tmp;         //最大的数字(堆顶)移到最后
        Adjust(a,1,i-1);  //将剩余的前i-1个数字调整为最大堆
    }


}

int findContentChildren(int* g, int gSize, int* s, int sSize){
   
    int i=0;
    int j=0;
    int cnt=0;
    int s1[sSize+1];
    int g1[gSize+1];
    memset(g1,0,sizeof(int)*(gSize+1));
    memset(s1,0,sizeof(int)*(sSize+1));
        
    if(sSize==0 || gSize==0 ) return 0;
    
    
    for(i=1;i<=gSize;i++){
        g1[i]=g[i-1];
    }
    for(i=1;i<=sSize;i++){
        s1[i]=s[i-1];
    }

    buildmaxHeap(s1,sSize);
    buildmaxHeap(g1,gSize);
    Hsort(s1,sSize);
    Hsort(g1,gSize);

  /*for(i=1;i<=gSize;i++){
        printf("%d ",g1[i]);
    }*/
    
    i=1;j=1;
    if(g1[0]>s1[sSize-1]) return 0;
    
    while(i<=gSize && j<=sSize){
        if(g1[i]<=s1[j]){
            cnt++;
            i++;
            j++;
        }else if(g1[i]>s1[j]) j++;

    }


    return cnt;
}

【代码三:归并排序】

void merge(int*a,int left,int right,int*a1){
    int mid;
    int i=0;
    int j=0;
    int k;
    
    if(right>left){
        mid=(left+right)/2;
            
        merge(a,left,mid,a1);
        merge(a,mid+1,right,a1);

    for(i=left,j=mid+1,k=i;i<=mid && j<=right;k++){
        if(a1[i]<a1[j]){
            a[k]=a1[i++];
        }else{
            a[k]=a1[j++];
        }
    }
    
    while(i<=mid){ 
        a[k++]=a1[i++];}
    while(j<=right){ 
        a[k++]=a1[j++];}
    }
    
    for(i=left;i<=right;i++){
            a1[i]=a[i];
    }
}

void mergesort(int* a,int asize,int* a1){
    merge(a,0,asize-1,a1);
}

int findContentChildren(int* g, int gSize, int* s, int sSize){
   
    int i=0;
    int j=0;
    int cnt=0;
    
    if(sSize==0 || gSize==0) return 0;

    int* g1=(int*)malloc(sizeof(int)*gSize);
    memset(g1,0,sizeof(int)*gSize);
    int* s1=(int*)malloc(sizeof(int)*sSize);
    memset(s1,0,sizeof(int)*sSize);
    
    mergesort(g,gSize,g1);
    mergesort(s,sSize,s1);

    if(g1[0]>s1[sSize-1]) return 0;
/*
    for(i=0;i<sSize;i++){
        printf("%d ",s[i]); //测试用
    }
    */
    while(i<gSize && j<sSize){
        if(g[i]<=s[j]){
            cnt++;
            i++;
            j++;
        }else if(g[i]>s[j]) j++;

    }

    

    return cnt;
}

【代码四:快速排序】

(抄的,不是太懂)

void swap(int *a,int*b){
    int tmp;
    tmp=*a;
    *a=*b;
    *b=tmp;
}

void qksort(int *a,int left,int right){
    if(left>=right) return;
    int i=left-1,j=right+1;
    int x = a[left+right>>1];

    while(i<j){
        do i++; while(a[i]<x);
        do j--; while(a[j]>x);
        if(i<j) swap(&a[i],&a[j]);
    }
    qksort(a,left,j);
    qksort(a,j+1,right);

}
int findContentChildren(int* g, int gSize, int* s, int sSize){
    int cnt=0;
    int i,j=0;
    
    qksort(g,0,gSize-1);
    qksort(s,0,sSize-1);

    for(i=0;i<gSize;i++){
        printf("%d ",g[i]);
    }
   
   
    for(i=0,j=0;i<gSize && j<sSize;){
        if(g[i]<=s[j]){
            i++;
            j++;
            cnt++;
        }else{
            j++;
        }
    }
    
    
    return cnt;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值