本文主要是介绍Leetcode刷题(四十二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
美丽下标对的数目(Easy)
给你一个下标从 0 开始的整数数组 nums 。如果下标对 i、j 满足 0 ≤ i < j < nums.length ,如果 nums[i] 的 第一个数字 和 nums[j] 的 最后一个数字 互质 ,则认为 nums[i] 和 nums[j] 是一组 美丽下标对 。返回 nums 中 美丽下标对 的总数目。对于两个整数 x 和 y ,如果不存在大于 1 的整数可以整除它们,则认为 x 和 y 互质 。换而言之,如果 gcd(x, y) == 1 ,则认为 x 和 y 互质,其中 gcd(x, y) 是 x 和 y 的 最大公因数 。示例 1:输入:nums = [2,5,1,4]
输出:5
解释:nums 中共有 5 组美丽下标对:
i = 0 和 j = 1 :nums[0] 的第一个数字是 2 ,nums[1] 的最后一个数字是 5 。2 和 5 互质,因此 gcd(2,5) == 1 。
i = 0 和 j = 2 :nums[0] 的第一个数字是 2 ,nums[2] 的最后一个数字是 1 。2 和 1 互质,因此 gcd(2,1) == 1 。
i = 1 和 j = 2 :nums[1] 的第一个数字是 5 ,nums[2] 的最后一个数字是 1 。5 和 1 互质,因此 gcd(5,1) == 1 。
i = 1 和 j = 3 :nums[1] 的第一个数字是 5 ,nums[3] 的最后一个数字是 4 。5 和 4 互质,因此 gcd(5,4) == 1 。
i = 2 和 j = 3 :nums[2] 的第一个数字是 1 ,nums[3] 的最后一个数字是 4 。1 和 4 互质,因此 gcd(1,4) == 1 。
因此,返回 5 。
示例 2:输入:nums = [11,21,12]
输出:2
解释:共有 2 组美丽下标对:
i = 0 和 j = 1 :nums[0] 的第一个数字是 1 ,nums[1] 的最后一个数字是 1 。gcd(1,1) == 1 。
i = 0 和 j = 2 :nums[0] 的第一个数字是 1 ,nums[2] 的最后一个数字是 2 。gcd(1,2) == 1 。
因此,返回 2 。
提示:2 <= nums.length <= 100
1 <= nums[i] <= 9999
nums[i] % 10 != 0
Related Topics
数组
哈希表
数学
计数
数论
思路分析1
首先想到的就是使用双循环的暴力解法,使用双循环逐个遍历数组,找到所有的美丽下标对。这里判断两个数是不是互质的函数写法是固定常用的GCD函数,如果返回值为1则代表两个数互质。
代码实现1
class Solution {public int countBeautifulPairs(int[] nums) {int result = 0;for (int i = 0; i < nums.length; i++){for (int j = i + 1;j < nums.length; j++){int a = nums[i];while (a >= 10){a = a / 10;}int b = nums[j] % 10;if (gcd(a, b)==1){result++;}}}return result;}public int gcd(int a, int b){while (b != 0){int temp = b;b = a % b;a = temp;}return a;}
}
思路分析2
上面的方法就是简答粗暴地遍历,我就思考有没有可能优化一点速度,这里我可以选择把相同数字出现的次数记录下来,那么下面只要出现了互质的数字直接就增加对应的次数。比如说,前三个数字的第一位都是‘3’,那么后面只要有一个数字的最后一位是与‘3’互质的,最后的结果就可以直接增加3。这样就减少了一定的重复工作。
代码实现2
class Solution {// 求两个数的最大公约数private int gcd(int a, int b) {while (b != 0) {int temp = b;b = a % b;a = temp;}return a;}public int countBeautifulPairs(int[] nums) {int[] cnt = new int[10]; // 已遍历 第一位数的计数int ans = 0;for (int x : nums) {// 获取第一个数字int first = 0;for (int tx = x; tx != 0; tx /= 10) {first = tx % 10;}// 获取最后一个数字int last = x % 10;// 遍历找之前是否有互质的for (int fir = 1; fir <= 9; fir++) {if (cnt[fir] != 0 && gcd(fir, last) == 1) {ans += cnt[fir];}}cnt[first]++; // 维护计数器}return ans;}
}
在这段代码中:
1.gcd 方法用于计算两个数的最大公约数。
2.countBeautifulPairs 方法计算美丽下标对的总数目。它遍历数组 nums,提取每个数的第一个和最后一个数字,并检查是否存在之前遍历过的数字与当前数的最后一个数字互质。
3.维护一个计数器 cnt,记录每个数字的第一个数字出现的次数。通过遍历 cnt,检查是否存在互质的数字对。
这篇关于Leetcode刷题(四十二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!