简体   繁体   中英

Is the time complexity for this function O(N) or O(N^2)?

I am trying to determine the time complexity for the following function.

The function reverses the order of words in a string and then reverses the order of letters in a word.

For example:

“the sky is blue” => “eulb si yks eht”

var reverseString = function(s) {
  let str = s.split(' ')
  let word;
  let wordRev;
  let result = [];
  let countI = 0
  let countJ = 0    

  //lets call this loop "i"
  for(let i=str.length-1; i>=0; i--) {
    word = str[i]
    wordRev = ""
    countI +=1

    //lets call this loop "j"      
    for(let j=word.length-1; j>=0; j--) {
      wordRev += word[j]
      countJ+=1
    }
    result.push(wordRev)
  }
  return result.join(" ")
};

Although there are two nested loops, I believe the time complexity is O(n) and I will give two scenarios as an example.

•     Scenario 1:
   ⁃    s.length: 22
   ⁃    input: “thisisreallylongstring”
   ⁃    str: [“thisisreallylongstring”]
   ⁃    i loop count total: 1
   ⁃    j loop count total: 22
•   Scenario 2
   ⁃    s.length = 11
   ⁃    input: “s t r i n g”
   ⁃    str: [“s”, “t”, “r”, “i”, “n”, “g”]
   ⁃    j loop count total: 6
   ⁃    i loop count total: 6

The count total of loops i and j are roughly equal to the length on the input, which leads me to believe that even though there are two nested loops it is still O(n) complexity.

Am i wrong in my line of thinking?

Two factors are at play here:

  1. Your algorithm itself is O(n). The substrings processed in each inner loop are disjoint. That is, you have two nested loops, but the part of the string processed in the inner loop is never repeated by separate iterations in the outer loop. Each inner loop gets its own separate substring, and when you add them together, it's O(n).

  2. Appending strings this way makes the algorithm O(n^2). Strings are immutable so each call to wordRev += word[j] will create a brand new string. In the worst case, such as for "thisisreallylongstring" , you end up creating "g", "gn", "gni", ... as intermediate strings. Adding them together, it's O(n^2).

So the overall answer is O(n^2).

All you really care about is how many times the inner loop runs and if everything you are doing in the loops is constant time. In your case the inner loop always runs n times where n is the number of letters in your sentence. For testing you can make some fake sentences easily and actually count how many times the loop runs. So with a sentence made with: let str = Array.from({length: 20}, ()=>'a'.repeat(20)).join(' ') you'll find the inner loop runs exactly 400 times. Which is exactly how many letters you have. You sometimes need to be careful with the javascript functions because they don't always run in constant time — for example if you where splicing arrays in the loops, but you don't appear to be doing that here. Everything should run in linear time. So O(n) where n is the number of letters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM