Number of Beautiful Pairs
EasyUpdated: Aug 2, 2025
Practice on:
Problem
You are given a 0-indexed integer array nums. A pair of indices i, j
where 0 <= i < j < nums.length is called beautiful if the first digit of
nums[i] and the last digit of nums[j] are coprime.
Return the total number of beautiful pairs innums.
Two integers x and y are coprime if there is no integer greater than 1 that divides both of them. In other words, x and y are coprime if gcd(x, y) == 1, where gcd(x, y) is the greatest common divisor of x and y.
Examples
Example 1
Input: nums = [2,5,1,4]
Output: 5
Explanation: There are 5 beautiful pairs in nums:
When i = 0 and j = 1: the first digit of nums[0] is 2, and the last digit of nums[1] is 5. We can confirm that 2 and 5 are coprime, since gcd(2,5) == 1.
When i = 0 and j = 2: the first digit of nums[0] is 2, and the last digit of nums[2] is 1. Indeed, gcd(2,1) == 1.
When i = 1 and j = 2: the first digit of nums[1] is 5, and the last digit of nums[2] is 1. Indeed, gcd(5,1) == 1.
When i = 1 and j = 3: the first digit of nums[1] is 5, and the last digit of nums[3] is 4. Indeed, gcd(5,4) == 1.
When i = 2 and j = 3: the first digit of nums[2] is 1, and the last digit of nums[3] is 4. Indeed, gcd(1,4) == 1.
Thus, we return 5.
Example 2
Input: nums = [11,21,12]
Output: 2
Explanation: There are 2 beautiful pairs:
When i = 0 and j = 1: the first digit of nums[0] is 1, and the last digit of nums[1] is 1. Indeed, gcd(1,1) == 1.
When i = 0 and j = 2: the first digit of nums[0] is 1, and the last digit of nums[2] is 2. Indeed, gcd(1,2) == 1.
Thus, we return 2.
Constraints
2 <= nums.length <= 1001 <= nums[i] <= 9999nums[i] % 10 != 0
Solution
Method 1 – Brute Force with Digit Extraction
Intuition
For each pair (i, j) with i < j, extract the first digit of nums[i] and last digit of nums[j], check if they are coprime.
Approach
- For each i < j, extract first digit of nums[i] and last digit of nums[j].
- Check gcd(first, last) == 1.
- Count and return total pairs.
Code
C++
#include <vector>
using namespace std;
class Solution {
public:
int beautifulPairs(vector<int>& nums) {
int n = nums.size(), ans = 0;
auto first = [](int x) { while (x >= 10) x /= 10; return x; };
auto last = [](int x) { return x % 10; };
auto gcd = [](int a, int b) { while (b) { int t = b; b = a % b; a = t; } return a; };
for (int i = 0; i < n; ++i)
for (int j = i+1; j < n; ++j)
if (gcd(first(nums[i]), last(nums[j])) == 1) ++ans;
return ans;
}
};
Go
func beautifulPairs(nums []int) int {
n := len(nums); ans := 0
first := func(x int) int { for x >= 10 { x /= 10 }; return x }
last := func(x int) int { return x % 10 }
gcd := func(a, b int) int { for b != 0 { a, b = b, a%b }; return a }
for i := 0; i < n; i++ {
for j := i+1; j < n; j++ {
if gcd(first(nums[i]), last(nums[j])) == 1 { ans++ }
}
}
return ans
}
Java
class Solution {
public int beautifulPairs(int[] nums) {
int n = nums.length, ans = 0;
for (int i = 0; i < n; ++i)
for (int j = i+1; j < n; ++j)
if (gcd(first(nums[i]), last(nums[j])) == 1) ans++;
return ans;
}
int first(int x) { while (x >= 10) x /= 10; return x; }
int last(int x) { return x % 10; }
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
}
Kotlin
class Solution {
fun beautifulPairs(nums: IntArray): Int {
fun first(x: Int) = generateSequence(x) { it/10 }.first { it < 10 }
fun last(x: Int) = x % 10
fun gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
var ans = 0
for (i in nums.indices)
for (j in i+1 until nums.size)
if (gcd(first(nums[i]), last(nums[j])) == 1) ans++
return ans
}
}
Python
from math import gcd
class Solution:
def beautifulPairs(self, nums: List[int]) -> int:
def first(x):
while x >= 10: x //= 10
return x
def last(x): return x % 10
return sum(gcd(first(nums[i]), last(nums[j])) == 1 for i in range(len(nums)) for j in range(i+1, len(nums)))
Rust
impl Solution {
pub fn beautiful_pairs(nums: Vec<i32>) -> i32 {
fn first(x: i32) -> i32 { let mut x = x; while x >= 10 { x /= 10; } x }
fn last(x: i32) -> i32 { x % 10 }
fn gcd(a: i32, b: i32) -> i32 { if b == 0 { a } else { gcd(b, a % b) } }
let n = nums.len(); let mut ans = 0;
for i in 0..n {
for j in i+1..n {
if gcd(first(nums[i]), last(nums[j])) == 1 { ans += 1; }
}
}
ans
}
}
TypeScript
function beautifulPairs(nums: number[]): number {
const first = (x: number) => { while (x >= 10) x = Math.floor(x/10); return x; };
const last = (x: number) => x % 10;
const gcd = (a: number, b: number): number => b === 0 ? a : gcd(b, a % b);
let ans = 0;
for (let i = 0; i < nums.length; ++i)
for (let j = i+1; j < nums.length; ++j)
if (gcd(first(nums[i]), last(nums[j])) === 1) ans++;
return ans;
}
Complexity
- ⏰ Time complexity:
O(n^2) - 🧺 Space complexity:
O(1)