Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

I was amazed to find that there is a way to reduce the times you loop on an array to find if a element is contained once.

One would think that the only way would be to loop through the whole array, and increasing a variable every time you find a match, and then check if it is equal to 1. However, lets look at this JavaScript code:

function isOnce(itm,arr){
    var first_match=-1;
    for(var i=0,len=arr.length;i<len;i++){
        if(arr[i]===itm){
            first_match=i;
            break;
        }
    }
    if(first_match!=-1){
        var last_match=-1;
        for(i=arr.length-1;i>first_match;i--){
            if(arr[i]===itm){
                last_match=i;
                break;
            }
        }
        if(last_match==-1){
            return true;
        }
    }
    return false;
}

It can reduce the times you loop when these two points met:

  • There are 2 or more matches
  • The first and last match are at least 1 space apart

so, arr=["a", ...(thousands of items here)... ,"a"]; //we only looped 2 times

I was wondering if there are other ways to reduce the looping in *certain cases.

*There are obviously some cases that one will need to loop through every item on these worst-case scenarios. So it might not work all the time.

share|improve this question
1  
This doesn't look like a competition to me. Migrate to SO? – Peter Taylor Feb 13 '12 at 8:01
3  
@PeterTaylor, I think my question is just dumb, as 'ratchet freak' pointed out, it will remain at O(n) regardless on any algorithm. I think my question should be deleted or closed to prevent people from lowering their IQ – ajax333221 Feb 13 '12 at 18:04

closed as off topic by gnibbler Mar 6 '12 at 6:10

Questions on Programming Puzzles & Code Golf Stack Exchange are expected to relate to programming puzzle or code golf within the scope defined in the FAQ. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about closed questions here.

1 Answer

up vote 3 down vote accepted

D

bool containsOnce(E,R)(R haystack,E needle){
     bool foundOnce=false;
     foreach(e;haystack){
          if(e==needle){
              if(foundOnce)return false;
              foundOnce=true;
          }
     }
     return foundOnce;
}

this is pretty much the best case on unsorted data, you loop until you find a match and then set a flag to true and continue looping, when you find the second match return false immediately, when you looped over the entire thing return state of the flag

this has better timebounds when the double match is found near the beginning of the array (and in general when the items are close together) (but is better in a code-golf contest ;) )

in interest of time bound you'll remain at O(n) regardless on any algorithm (sometimes there simply are no improvements possible except with micro-optimizations). as finding a single match (a subproblem of the current problem) in an unsorted array is O(n)

share|improve this answer
it make a lot of sense, I really don't know what I was thinking with those two loops – ajax333221 Feb 13 '12 at 3:47

Not the answer you're looking for? Browse other questions tagged or ask your own question.