1512. 好数对的数目 的三种解法

1512. 好数对的数目


给你一个整数数组 nums 。

如果一组数字 (i,j) 满足 nums[i] == nums[j] 且 i < j ,就可以认为这是一组 好数对 。

返回好数对的数目。

示例 1:

输入:nums = [1,2,3,1,1,3]
输出:4
解释:有 4 组好数对,分别是 (0,3), (0,4), (3,4), (2,5) ,下标从 0 开始
示例 2:

输入:nums = [1,1,1,1]
输出:6
解释:数组中的每组数字都是好数对
示例 3:

输入:nums = [1,2,3]
输出:0

提示:

1 <= nums.length <= 100
1 <= nums[i] <= 100

解法1

  看见输入数组和数的范围都不大,直接想到桶排序。先统计每个数出现的次数,然后求组合的个数。

int numIdenticalPairs(int* nums, int numsSize){
    int nums_index[101]={0};

    for(int i=1;i<=100;i++){
        for(int j=0;j<numsSize;j++){
            if(i == nums[j]){
                nums_index[i] += 1;
            }
        }
    }
    
    int res=0;
    for(int i=1;i<=100;i++){
        if(nums_index[i]>1){
            res += nums_index[i] * (nums_index[i]-1) / 2;
        }
    }
    return res;
}

  对这桶做一些改进:

int numIdenticalPairs(int* nums, int numsSize){
    int nums_index[101]={0};

    for(int j=0;j<numsSize;j++){     
        nums_index[ nums[j] ] += 1;
    }
   
    int res=0;
    for(int i=1;i<=100;i++){
        if(nums_index[i]>1){
            res += nums_index[i] * (nums_index[i]-1) >> 1;
        }
    }
    return res;
}

解法2

  双循环,本题用暴力双循环效果好像也不错

int numIdenticalPairs(int* nums, int numsSize){ 
    int res = 0;
    for(int i= 0; i < numsSize ;i++){
        for(int j=i+1; j <numsSize;j++){ 
            if(nums[i] == nums[j]) res++;
        }
    } 
    return res;
}

解法3

  这办法有点像1和2的结合。有解法1的桶思想,却没有用乘法,有解法2的加法思想,却省略一层循环。

int numIdenticalPairs(int* nums, int numsSize){ 
    int nums_index[101]={0};
    int res = 0;

    for(int i= 0; i < numsSize ;i++){
        res += nums_index[ nums[i] ];
        nums_index[ nums[i] ] +=1;
    } 

    return res;
}

总结

  解法1、2在某些case中用时都能击败100%的用户。但内存耗费都有点尴尬。解法3在时间和内存表现都非常好。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页