Problem Description:
We is asking for a function to take a positive integer value, and return a list of all positive integer pairs whose value S-when squared-sum to the given integer.
For example, given the parameter, the function could return both pairs of 5,0 and 3,4 because 5^2 + 0^2 = + 3^2 + 4 ^2 = 25.
We might express that in pseudo-code like this:
Allsquaredpairs (25) = = [[5,0],[3,4]];
The topic itself is relatively simple, that is, given an integer, the sum of squares equals the sequence of two numbers of that integer.
Solution Method 1: Traverse all numbers to get results
function Allsquarepairs (num) { var temp = math.sqrt (num); var result = []; For (Var i=0, i<=temp; i++) {for (var j=i; j<=temp; J + +) if (i*i+j*j==num) Result.push ([i,j]); } return result;}
However, although this method is correct, it cannot pass the test. Because the complexity of the algorithm is still quite large, it will take a long time for the large num to arrive at the result.
So how to reduce the complexity of it? I think the problem is mainly on the J traversal. For each i,j to be traversed from the beginning, this obviously contributes a lot of computational capacity.
I thought about it, maybe we can use a binary search, each given an I, the middle value between I and temp, if J is too large, then the previous interval will continue to traverse; too small, then change to the next interval.
Just as I racked my brains to think how to perfectly implant the dichotomy, suddenly a flash of light, in fact, there is no need to be so complex: given a I, in fact, we can calculate directly from the value of J, there is no need to traverse the ...
Method 2: Calculate the value of J directly
function Allsquaredpairs (num) { var temp = math.sqrt (num); var result = []; var j=0; for (var i=0; i<=temp; i++) { j=math.sqrt (num-i*i); if (Isint (j) && J>=i) Result.push ([i,j]); } return result;}
Above, traversing I, by calculating (num-i^2) The square root, determine whether it is an integer, if so, then get a set of values, otherwise continue to retrieve. As a result, less than one cycle of computation is greatly reduced, and it is logical to pass the test.
Improvement of the implementation of 1> Isint ()
Isint () in the above code indicates whether a number is an integer, or true, otherwise false.
Of course, there is no need to use the function, the simple expression will be more convenient, here just to occupy bits.
So the question is, how do you tell if a number is an integer?
Before I play this problem, I know there are these methods:
A>math.floor (num) = = num
Rounding a given number, or an integer if it is equal to the original number.
B>parseint (num) = = num
The same as above, just using a different approach
C> "^-?//d+$"
Of course, you can also use powerful regular expressions.
After I finished this problem, I realized that there was a more concise form:
D>num = = num | 0
Does this seem like a or an operation? The practice proves that the effect of num|0 is the same as that of Math.floor (num).
e>num%1 = = 0
To 1 to take the surplus ... I'm so familiar with the take-up sign that I don't even think about how it will work with floating-point numbers ...
The judging condition of 2> redundancy
Next to Isint () We also made a j>i condition to avoid repeating sequences such as [0,5] and [5,0].
In fact, this can be completely filtered out when setting the value of temp. Just let Temp=math.sqrt (NUM/2) instead of temp=math.sqrt (num), you can get rid of the j>i of the latter condition.
[Codewars] [JS] How to determine whether a given number is an integer