Pythagorean Triplet Detection
Problem
Given an array of integers, determine whether it contains a Pythagorean triplet. Recall that a Pythagorean triplet (a, b, c) is defined by the equation a^2 + b^2 = c^2.
Examples
Example 1
Input: [3, 4, 5, 6, 8]
Output: true
Explanation: The array contains the Pythagorean triplet (3, 4, 5) because 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
Example 2
Input: [1, 2, 3]
Output: false
Explanation: No three numbers in the array satisfy the Pythagorean theorem. 1^2 + 2^2 = 5, which is not equal to 3^2 = 9.
Example 3
Input: [5, 3, 4, 6, 13, 12]
Output: true
Explanation: The array contains the Pythagorean triplet (5, 12, 13) because 5^2 + 12^2 = 25 + 144 = 169 = 13^2.
Example 4
Input: [1]
Output: false
Explanation: A single element cannot form a triplet.
Solution
Method 1 - Brute Force
Intuition
The simplest approach is to check all possible combinations of three numbers from the array and verify if they satisfy the Pythagorean theorem. For each triplet, we need to check if the sum of squares of two smaller numbers equals the square of the largest number.
Approach
- Iterate through all possible triplets using three nested loops
- For each triplet (a, b, c), sort them to identify the largest value
- Check if
a^2 + b^2 = c^2where c is the largest value - Return true if any triplet satisfies the condition
- Return false if no valid triplet is found
Code
C++
class Solution {
public:
bool hasPythagoreanTriplet(vector<int>& nums) {
int n = nums.size();
if (n < 3) return false;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = j + 1; k < n; k++) {
vector<int> triplet = {nums[i], nums[j], nums[k]};
sort(triplet.begin(), triplet.end());
if (triplet[0] * triplet[0] + triplet[1] * triplet[1] == triplet[2] * triplet[2]) {
return true;
}
}
}
}
return false;
}
};
Go
func hasPythagoreanTriplet(nums []int) bool {
n := len(nums)
if n < 3 {
return false
}
for i := 0; i < n; i++ {
for j := i + 1; j < n; j++ {
for k := j + 1; k < n; k++ {
triplet := []int{nums[i], nums[j], nums[k]}
sort.Ints(triplet)
if triplet[0]*triplet[0] + triplet[1]*triplet[1] == triplet[2]*triplet[2] {
return true
}
}
}
}
return false
}
Java
class Solution {
public boolean hasPythagoreanTriplet(int[] nums) {
int n = nums.length;
if (n < 3) return false;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = j + 1; k < n; k++) {
int[] triplet = {nums[i], nums[j], nums[k]};
Arrays.sort(triplet);
if (triplet[0] * triplet[0] + triplet[1] * triplet[1] == triplet[2] * triplet[2]) {
return true;
}
}
}
}
return false;
}
}
Python
class Solution:
def has_pythagorean_triplet(self, nums: List[int]) -> bool:
n = len(nums)
if n < 3:
return False
for i in range(n):
for j in range(i + 1, n):
for k in range(j + 1, n):
triplet = sorted([nums[i], nums[j], nums[k]])
if triplet[0]**2 + triplet[1]**2 == triplet[2]**2:
return True
return False
Complexity
- ⏰ Time complexity:
O(n^3 log 3), where n is the length of the array. We check all possible triplets and sort each triplet of 3 elements - 🧺 Space complexity:
O(1), only using constant extra space for temporary variables
Method 2 - Hash Set Optimization
Intuition
Instead of checking all triplets, we can optimize by fixing two numbers and checking if the third number (which would complete the Pythagorean triplet) exists in the array. We use a hash set for O(1) lookup.
Approach
- Store all numbers in a hash set for O(1) lookup
- Iterate through all pairs of numbers (a, b)
- Calculate what the third number c should be:
c = sqrt(a^2 + b^2) - Check if c is an integer and exists in the hash set
- Return true if such a triplet is found
Code
C++
class Solution {
public:
bool hasPythagoreanTriplet(vector<int>& nums) {
if (nums.size() < 3) return false;
unordered_set<int> numSet(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++) {
for (int j = i + 1; j < nums.size(); j++) {
int a = nums[i], b = nums[j];
long long cSquared = (long long)a * a + (long long)b * b;
int c = sqrt(cSquared);
if ((long long)c * c == cSquared && numSet.count(c)) {
return true;
}
}
}
return false;
}
};
Go
func hasPythagoreanTriplet(nums []int) bool {
if len(nums) < 3 {
return false
}
numSet := make(map[int]bool)
for _, num := range nums {
numSet[num] = true
}
for i := 0; i < len(nums); i++ {
for j := i + 1; j < len(nums); j++ {
a, b := nums[i], nums[j]
cSquared := a*a + b*b
c := int(math.Sqrt(float64(cSquared)))
if c*c == cSquared && numSet[c] {
return true
}
}
}
return false
}
Java
class Solution {
public boolean hasPythagoreanTriplet(int[] nums) {
if (nums.length < 3) return false;
Set<Integer> numSet = new HashSet<>();
for (int num : nums) {
numSet.add(num);
}
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
int a = nums[i], b = nums[j];
long cSquared = (long) a * a + (long) b * b;
int c = (int) Math.sqrt(cSquared);
if ((long) c * c == cSquared && numSet.contains(c)) {
return true;
}
}
}
return false;
}
}
Python
class Solution:
def has_pythagorean_triplet(self, nums: List[int]) -> bool:
if len(nums) < 3:
return False
num_set = set(nums)
for i in range(len(nums)):
for j in range(i + 1, len(nums)):
a, b = nums[i], nums[j]
c_squared = a * a + b * b
c = int(c_squared ** 0.5)
if c * c == c_squared and c in num_set:
return True
return False
Complexity
- ⏰ Time complexity:
O(n^2), where n is the length of the array. We check all pairs and do O(1) lookup in hash set - 🧺 Space complexity:
O(n), for storing all numbers in the hash set
Method 3 - Sort and Two Pointers
Intuition
We can sort the array and for each potential hypotenuse (largest value), use two pointers to find if there exist two numbers whose squares sum to the hypotenuse's square. This approach leverages the sorted order to efficiently search for the pair.
Approach
- Sort the array in ascending order
- Iterate from the largest element backwards (potential hypotenuse)
- For each hypotenuse candidate, use two pointers from the beginning to find a pair
- Use left and right pointers to check if
left^2 + right^2 = hypotenuse^2 - Move pointers based on the comparison result
Code
C++
class Solution {
public:
bool hasPythagoreanTriplet(vector<int>& nums) {
if (nums.size() < 3) return false;
sort(nums.begin(), nums.end());
for (int i = nums.size() - 1; i >= 2; i--) {
int left = 0, right = i - 1;
long long target = (long long)nums[i] * nums[i];
while (left < right) {
long long sum = (long long)nums[left] * nums[left] + (long long)nums[right] * nums[right];
if (sum == target) {
return true;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
return false;
}
};
Go
func hasPythagoreanTriplet(nums []int) bool {
if len(nums) < 3 {
return false
}
sort.Ints(nums)
for i := len(nums) - 1; i >= 2; i-- {
left, right := 0, i-1
target := nums[i] * nums[i]
for left < right {
sum := nums[left]*nums[left] + nums[right]*nums[right]
if sum == target {
return true
} else if sum < target {
left++
} else {
right--
}
}
}
return false
}
Java
class Solution {
public boolean hasPythagoreanTriplet(int[] nums) {
if (nums.length < 3) return false;
Arrays.sort(nums);
for (int i = nums.length - 1; i >= 2; i--) {
int left = 0, right = i - 1;
long target = (long) nums[i] * nums[i];
while (left < right) {
long sum = (long) nums[left] * nums[left] + (long) nums[right] * nums[right];
if (sum == target) {
return true;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
return false;
}
}
Python
class Solution:
def has_pythagorean_triplet(self, nums: List[int]) -> bool:
if len(nums) < 3:
return False
nums.sort()
for i in range(len(nums) - 1, 1, -1):
left, right = 0, i - 1
target = nums[i] * nums[i]
while left < right:
current_sum = nums[left] * nums[left] + nums[right] * nums[right]
if current_sum == target:
return True
elif current_sum < target:
left += 1
else:
right -= 1
return False
Complexity
- ⏰ Time complexity:
O(n^2), where n is the length of the array. Sorting takes O(n log n) and the two-pointer search takes O(n^2) in worst case - 🧺 Space complexity:
O(1), only using constant extra space for pointers and variables