JavaScript 打印出有序数组中所有形成等差数列的三元组
等差数列(AP)是指相邻元素之间的差恒定。我们将使用三种方法来打印出有序数组中形成AP的所有三元组:原生方法、二分查找方法和双指针方法。
问题介绍
在这个问题中,我们给定一个有序数组,意味着所有元素都是递增的。我们需要找到数组中形成AP的三个元素。例如 −
给定数组:1 5 2 4 3
从给定数组中我们可以找到两个三元组:1 2 3 和 5 4 3,因为相邻元素之间的差是相等的。由于问题要求只找到三元组,所以我们不会找到更长的序列。
现在我们来讨论找到这些三元组的方法 −
方法
原生方法
在这种方法中,我们只是使用一个循环遍历数组,并在每次迭代中运行另一个数组来查找大于当前索引的数字。然后,我们再次在第一个嵌套数组内实现一个嵌套数组来找到可以形成AP的元素。下面是代码示例 −
示例
// function to find all the triplets
function findAP(arr){
var n = arr.length
// traversing over the array
for(var i = 0; i< n;i++){
for(var j = i+1;j<n;j++){
for(var k = j+1; k < n; k++){
if(arr[j] - arr[i] == arr[k] - arr[j]) {
console.log("Triplet is: " + arr[i] + " " + arr[j] + " " + arr[k]);
}
}
}
}
}
// defining the array and calling the function
arr = [1, 5, 2, 4, 3]
findAP(arr)
上述代码的时间复杂度是O(N),其中N是数组的大小。
上述代码的空间复杂度是O(1),因为我们没有使用任何额外的空间。
进一步优化
在之前的方法中,当我们有两个元素时,我们可以根据公差找到第三个元素,所以为了找到第三个元素,我们可以使用二分搜索而不是线性搜索,以降低上述代码的时间复杂度。
示例
// function for binary search
var binarySearch = function (arr, x, start, end) {
if (start > end) return false;
var mid=Math.floor((start + end)/2);
if (arr[mid]===x) return true;
if(arr[mid] > x)
return binarySearch(arr, x, start, mid-1);
else
return binarySearch(arr, x, mid+1, end);
}
// function to find all the tripletes
function findAP(arr){
var n = arr.length
// traversing over the array
for(var i = 0; i< n;i++){
for(var j = i+1;j<n;j++){
// third element will be
var third = 2*arr[j]-arr[i];
if(binarySearch(arr,third,j+1,n)){
console.log("Triplet is: " + arr[i] + " " + arr[j] + " " + third);
}
}
}
}
// defining the array and calling the function
arr = [1, 5, 2, 4, 3]
findAP(arr)
以上代码的时间复杂度O(N),其中N为数组的大小。
以上代码的空间复杂度为O(1),因为我们没有使用额外的空间。
高效方法
在这个方法中,我们将使用两个指针,并找到与当前位置相同差异的元素。让我们来看看代码−
示例
// function to find all the triplets
function findAP(arr){
var n = arr.length
// traversing over the array
for(var i = 1; i< n;i++) {
var bptr = i-1
var fptr = i+1
while(bptr >= 0 && fptr < n) {
if(arr[i] - arr[bptr] == arr[fptr] - arr[i]){
console.log("Triplet is: " + arr[bptr] + " " + arr[i] + " " + arr[fptr]);
bptr--;
fptr++;
}
else if(arr[i] - arr[bptr] > arr[fptr] - arr[i]){
fptr++;
}
else{
bptr--;
}
}
}
}
// defining the array and calling the function
arr = [1, 4, 7, 10, 13, 16]
findAP(arr)
上述代码的时间复杂度为O(N*N),其中N是给定数组的大小,上述方法的空间复杂度为O(1),因为我们没有使用任何额外的空间。
注意 − 前两种方法适用于任何类型的数组,无论是已排序还是未排序的,但是最后一种方法仅适用于排序数组,并且如果数组未排序,我们可以将其排序并且仍然该方法将是所有其他方法中最好的。
结论
在本教程中,我们实现了一个JavaScript程序,以打印给定排序数组中形成AP的所有三个元素组。AP是等差数列,其中连续两个元素之间的差值始终相同。我们介绍了三种方法:时间复杂度为O(NNN)的原生方法,时间复杂度为O(NNlog(N))的二分搜索方法,以及双指针方法。