0
点赞
收藏
分享

微信扫一扫

《算法基础》计数法

guanguans 2022-01-25 阅读 20
算法

目录

1、LeetCode——1748. 唯一元素的和

2、LeetCode——387. 字符串中的第一个唯一字符

3、LeetCode——1941. 检查是否所有字符出现次数相同

 4、LeetCode——448. 找到所有数组中消失的数字

5、LeetCode——1512. 好数对的数目

6、LeetCode——1711. 大餐计数


1、LeetCode——1748. 唯一元素的和

示例1:

示例2:

示例3:

 思路:因为数据个数最多100个不是很大且最少有一个,又因为数据元素大小都是在1-100之间的,所以可以创建一个大小为101的数组,用来存1-100这100个数的出现次数,最后遍历该数组找出出现次数为1的数并相加。

代码及详情:

int sumOfUnique(int* nums, int numsSize){
    int arr[101];                        //计数数组
    memset(arr,0,sizeof(arr));           //初始化数组
    int sum=0;                           //和
    for(int i=0;i<numsSize;i++){         //先把出现过的数字都找出来
        ++arr[nums[i]];                  //加加表示次数加一
    }
    for(int i=1;i<=100;i++){             //从1开始,因为nums里的元素都大于等于1,所以下标为0的位置没用
        if(arr[i]==1)                    //出现次数为1
            sum+=i;                      //累加
    }
    return sum;
}

2、LeetCode——387. 字符串中的第一个唯一字符

示例:

 思路:找到第一个不重复的字符,用计数法的法,就先将每个字符的出现次数记录下来,然后在找到出现次数为1的字符并返回下标。可以用一个大小为26的数组来计数,因为只有26个英文字母。

代码及详情:

int firstUniqChar(char * s){
    int len=strlen(s);
    int count[26];                //因为只有26个小写字母
    memset(count,0,sizeof(count));//初始化

    //先将每个字符出现的次数记录下来
    for(int i=0;i<len;i++){
        count[s[i]-'a']++;
    }

    //再查找次数为1的字符,返回下标
    for(int i=0;i<len;i++){
        if(count[s[i]-'a']==1)
            return i;
    }
    return -1;
}

3、LeetCode——1941. 检查是否所有字符出现次数相同

示例1:

示例2:

思路:和上一题差不多,用一个大小为26的数组来存放每一个字符出现的次数,最后循环遍历,如果有出现次数不一样的就返回false。

代码及详情

bool areOccurrencesEqual(char * s){
    int count[26];                                      //计数数组
    memset(count,0,sizeof(count));                      //初始化数组
    int len=strlen(s);                                  //字符串长度
    for(int i=0;i<len;i++){                             //统计出现次数
        ++count[s[i]-'a'];
    }
    //方式一:
    // for(int i=0;i<26;i++){                           //比较出现次数是否都一样
    //     if(count[s[0]-'a']!=count[i]&&count[i]!=0)
    //         return false;
    // }
    //方式二:
    for(int i=0;i<len-1;i++){                           //比较出现次数是否都一样
        if(count[s[i]-'a']!=count[s[i+1]-'a'])
            return false;
    }
    return true;
}

 4、LeetCode——448. 找到所有数组中消失的数字

 

 思路:用一个大小为nums.length的计数数组用来统计每一位数字是否出现过,然后在遍历该数组判断是否有为0的位置,有的话下标就是消失的数。

代码及其详情:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize){
    int count[numsSize+1];                          //计数数组
    int* res=(int*)malloc(sizeof(int)*numsSize);    //返回的数组
    int j=0;                
    memset(count,0,sizeof(count));                  //初始化计数数组
    for(int i=0;i<numsSize;i++){                    //记录出现的数字
        ++count[nums[i]];               
    }   
    for(int i=1;i<=numsSize;i++){                   //将没有出现的数字存到res数组
        if(count[i]==0)
            res[j++]=i;
    }
    *returnSize=j;                                  //数组的大小
    return res;
}

5、LeetCode——1512. 好数对的数目

 思路:题目意思就是计算重复出现的数字有多少种排列方式,一个数字出现了n次就会有Cn2个好数对,所以还是要知道重复了多少次。

代码及详情如下:

int numIdenticalPairs(int* nums, int numsSize){
    int count[101];                     //计数数组
    int sum=0;  
    memset(count,0,sizeof(count));      //初始化数组
    for(int i=0;i<numsSize;i++){        //记录数字的出现次数
        ++count[nums[i]];
    }
    for(int i=0;i<101;i++){             //判断出现次数大于1的数字
        if(count[i]>1){
            sum+=count[i]*(count[i]-1)/2;
        }
    }
    return sum;
    //双循环暴力写法
    //int count=0;   
    // for(int i=0;i<numsSize;i++){
    //     for(int j=0;j<numsSize;j++){
    //         if(nums[i]==nums[j]&&i<j)
    //             count++;
    //     }
    // }
    // return count;
}

6、LeetCode——1711. 大餐计数

 思路:题目意思就是找到一个数组里面有几对数能加起来等于2的幂,根据提示,数组里的最大元素=2^20,所以两个数加起来的最大和=2^21,所以满足题目要求的数一定在:2^0,2^1,2^2.......2^20,2^21这22个数之间。

        我们可以枚举一个数x,然后枚举他们的和sum,再得到另一个数other:other=sum-x;然后累加上other的在数组里的出现次数,最后返回这个累加和%1000000007就是结果。

代码及详情:

int countPairs(int* deliciousness, int deliciousnessSize){
    int count[(1<<21)+1];                   //计数数组
    memset(count,0,sizeof(count));          //初始化数组
    int ans,other;                          //ans是结果
    for(int i=0;i<deliciousnessSize;i++){   //遍历数组里的元素
        for(int sum=1;sum<=(1<<21);sum*=2){  //枚举每一种结果,因为结果是2的幂,所以sum每次乘2
            other=sum-deliciousness[i];     //可以枚举出other
            if(other<0) 
                continue;
//other存在说明可以和当前的deliciousness[i]组成大餐,但又要求other是数组里的元素,所以结果数要加上other在数组里的出现次数
            ans+=count[other];              
            ans%=1000000007;            
        }
        ++count[deliciousness[i]];          //记录这个数的出现次数,这里的操作才是记录出现次数
    }
    return ans;
}
举报

相关推荐

0 条评论