Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP built in functions complexity (isAnagramOfPalindrome function)

I've been googling for the past 2 hours, and I cannot find a list of php built in functions time and space complexity. I have the isAnagramOfPalindrome problem to solve with the following maximum allowed complexity:

expected worst-case time complexity is O(N)

expected worst-case space complexity is O(1) (not counting the storage required for input arguments).

where N is the input string length. Here is my simplest solution, but I don't know if it is within the complexity limits.

class Solution { 

    // Function to determine if the input string can make a palindrome by rearranging it
    static public function isAnagramOfPalindrome($S) {

        // here I am counting how many characters have odd number of occurrences
        $odds = count(array_filter(count_chars($S, 1), function($var) {
            return($var & 1);
        }));
        // If the string length is odd, then a palindrome would have 1 character with odd number occurrences
        // If the string length is even, all characters should have even number of occurrences
        return (int)($odds == (strlen($S) & 1));
    }
}

echo Solution :: isAnagramOfPalindrome($_POST['input']);

Anyone have an idea where to find this kind of information?

EDIT

I found out that array_filter has O(N) complexity, and count has O(1) complexity. Now I need to find info on count_chars, but a full list would be very convenient for future porblems.

EDIT 2

After some research on space and time complexity in general, I found out that this code has O(N) time complexity and O(1) space complexity because:

The count_chars will loop N times (full length of the input string, giving it a start complexity of O(N) ). This is generating an array with limited maximum number of fields (26 precisely, the number of different characters), and then it is applying a filter on this array, which means the filter will loop 26 times at most. When pushing the input length towards infinity, this loop is insignificant and it is seen as a constant. Count also applies to this generated constant array, and besides, it is insignificant because the count function complexity is O(1). Hence, the time complexity of the algorithm is O(N).

It goes the same with space complexity. When calculating space complexity, we do not count the input, only the objects generated in the process. These objects are the 26-elements array and the count variable, and both are treated as constants because their size cannot increase over this point, not matter how big the input is. So we can say that the algorithm has a space complexity of O(1).

Anyway, that list would be still valuable so we do not have to look inside the php source code. :)

like image 779
Skatch Avatar asked Aug 19 '15 15:08

Skatch


1 Answers

A probable reason for not including this information is that is is likely to change per release, as improvements are made / optimizations for a general case.

PHP is built on C, Some of the functions are simply wrappers around the c counterparts, for example hypot a google search, a look at man hypot, in the docs for he math lib http://www.gnu.org/software/libc/manual/html_node/Exponents-and-Logarithms.html#Exponents-and-Logarithms

The source actually provides no better info https://github.com/lattera/glibc/blob/a2f34833b1042d5d8eeb263b4cf4caaea138c4ad/math/w_hypot.c (Not official, Just easy to link to)

Not to mention, This is only glibc, Windows will have a different implementation. So there MAY even be a different big O per OS that PHP is compiled on

Another reason could be because it would confuse most developers. Most developers I know would simply choose a function with the "best" big O

a maximum doesnt always mean its slower

http://www.sorting-algorithms.com/

Has a good visual prop of whats happening with some functions, ie bubble sort is a "slow" sort, Yet its one of the fastest for nearly sorted data. Quick sort is what many will use, which is actually very slow for nearly sorted data. Big O is worst case - PHP may decide between a release that they should optimize for a certain condition and that will change the big O of the function and theres no easy way to document that.

There is a partial list here (which I guess you have seen)

List of Big-O for PHP functions

Which does list some of the more common PHP functions.

For this particular example....

Its fairly easy to solve without using the built in functions.

Example code

function isPalAnagram($string) {
  $string = str_replace(" ", "", $string);
  $len = strlen($string);
  $oddCount = $len & 1;
  $string = str_split($string);
  while ($len > 0 && $oddCount >= 0) {
    $current = reset($string);
    $replace_count = 0;
    foreach($string as $key => &$char) {
      if ($char === $current){
        unset($string[$key]);
        $len--;
        $replace_count++;
        continue;
      }
    }
    $oddCount -= ($replace_count & 1);
  }

  return ($len - $oddCount) === 0;

}

Using the fact that there can not be more than 1 odd count, you can return early from the array.

I think mine is also O(N) time because its worst case is O(N) as far as I can tell.

Test

$a = microtime(true);
for($i=1; $i<100000; $i++) {
  testMethod("the quick brown fox jumped over the lazy dog");
  testMethod("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  testMethod("testest");
}
 printf("Took %s seconds, %s memory", microtime(true) - $a, memory_get_peak_usage(true));

Tests run using really old hardware My way

Took 64.125452041626 seconds, 262144 memory

Your way

Took 112.96145009995 seconds, 262144 memory

I'm fairly sure that my way is not the quickest way either.

I actually cant see much info either for languages other than PHP (Java for example).

I know a lot of this post is speculating about why its not there and theres not a lot drawing from credible sources, I hope its an partially explained why big O isnt listed in the documentation page though

like image 137
exussum Avatar answered Nov 06 '22 05:11

exussum