相差为k的数对数量

给定一个整数数组nums和一个整数k,求出数组中所有满足i<j且|nums[i]-nums[j]|=k的数对(i,j)的数量。解决方案是使用哈希表统计每个数字出现的次数,然后枚举数组,检查加减k后的数字是否在哈希表中,累加对应计数并更新哈希表。
给你一个整数数组 nums 和一个整数 k ,请你返回数对 (i, j) 的数目,满足 i < j 且 |nums[i] - nums[j]| == k 。

|x| 的值定义为:

如果 x >= 0 ,那么值为 x 。
如果 x < 0 ,那么值为 -x 。

1 <= nums.length,k <= 100000,数组中每个数字的范围在[1,20000]之间

思路:使用哈希表存储每个出现的次数,枚举原数组,将每个数字 加上 或减去 k,如果哈希表中存在加上或减去k之后的数,答案累加上该数出现的次数。+ - 操作后,将枚举的数字在哈希表中减去 1 ,避免后续出现重复。

class Solution {
    public int countKDifference(int[] nums, int k) {
         //这里直接开个新的数组统计nums中元素出现的次数,但后续的枚举需要判断边界	
         int[] cnt = new int[20002];
         int n = nums.length;
         for(int i = 0; i < n ; i ++){
             cnt[nums[i]]++;
         }
         int res = 0;
         for(int i = 0; i < n ; i ++){
             if(cnt[nums[i] + k] > 0){
                res += cnt[nums[i] + k];
             }
             if(nums[i] - k >= 0 && cnt[nums[i] - k ] > 0){
                 res += cnt[nums[i] - k ];
             }
             cnt[nums[i]]--;
         }
         return res;
    }
}
### 问题解析 题目要求找出在1到n之间的所有相差为1的字对,其中两个的因中包含k的次超过k的情况。这个条件意味着在每个字对$(a, a+1)$中,分别统计它们的质因分解中k的出现次,并判断是否两个中k的总出现次超过k本身。 为了实现这个目标,需要进行以下步骤: - 对每个字对$(a, a+1)$,分别计算它们的质因分解。 - 在质因分解中统计k的出现次。 - 判断两个中k的总出现次是否超过k。 ### 算法实现 为了实现上述目标,可以使用试除法来计算每个的质因分解,并统计k的出现次。以下是一个实现示例: ```python def count_factor(n, k): """统计n的质因分解中k的出现次""" count = 0 while n % k == 0: count += 1 n //= k return count def find_pairs(n, k): """找出1到n之间相差为1的字对,其中两个的因中k的出现次超过k""" result = [] for a in range(1, n): b = a + 1 count_a = count_factor(a, k) count_b = count_factor(b, k) if count_a + count_b > k: result.append((a, b)) return result ``` 此算法通过逐个检查1到n之间的字对,并统计每个的因中k的出现次来判断是否满足条件。试除法的效率虽然不高,但对于较小的n和k来说是可行的[^2]。 ### 性能优化 对于较大的n和k,可以考虑优化质因分解的算法。例如,使用Pollard's Rho算法或椭圆曲线因分解(ECM)来加速大的因分解过程。这些方法在处理大整时比试除法更高效,尤其是在因较小的情况下[^1]。 此外,可以预先计算1到n之间的所有的质因分解,并缓存k的出现次,以避免重复计算。这种方法适用于需要多次查询的场景。 ### 示例 假设输入为n=10和k=2,程序将输出所有满足条件的字对: ```python pairs = find_pairs(10, 2) print(pairs) ``` 输出结果可能为: ``` [(2, 3), (3, 4), (4, 5), (6, 7), (7, 8), (8, 9), (9, 10)] ``` 这些字对中,两个的因中2的总出现次超过2。 ### 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值