Please suggest if there is quicker way to find the negative number in a given array, provided that the array has only one negative number. I think sorting is an option, but it will be helpful if there is a quicker way.
Sorting won't be quicker than going through all the elements of the array (because to sort you also have to do that).
The fastest possible thing to do is to go through the all array and stop once you detect one negative number.
Just traverse the array. That is order n. Sorting is at best order n(log n); at worst n2.
Probably the fastest is to just scan the array until you find it.
If you're just doing this once, and don't need the array sorted for other purposes, it'll be faster to scan for the negative number than to do the sort. If, however, you need (or can use) the sorting for other purposes, or you may need to find the negative number several times, then sorting can end up saving time. Likewise, with some programs, spending extra time in preparation to get faster response when really crucial can be justified (but I've no idea whether that applies here or not).
Related
I was wondering whether it is even possible as a concept to have a Big-O-Notation of O(0) (in a very specific scenario).
Imagine I have a list with values and I want to sort it with Bubblesort. Suppose, however, that the list is already sorted. If I'm not mistaken, this would have a Big-O-Notation of O(n), where n is the number of elements.
Now, I want to express the Big-O-Notation of the swaps I've had to make to get the list sorted. In this very specific scenario, no swaps were made. So, would I go about it by saying that the swaps' Big-O-Notation is O(0) or is the minimum I can have O(1), and why?
The simplest complexity is O(1), constant time (or space, or whatever else you may be measuring, including number of swaps). That's constant, even if the value is zero.
In any case, sort functions are not O(1) because, at a minimum, you have to check it's sorted even if you don't make any swaps. Your particular measurement of swap count may give you O(1) but I'd be interested in the reasoning behind that being considered a useful metric :-)
http://katemats.com/interview-questions/ says:
You are given a sorted array and you want to find the number N. How do you do the search as quickly as possible (not just traversing each element)?
How would the performance of your algorithm change if there were lots of duplicates in the array?
My answer to the first question is binary search, which is O(log(n)), where n is the number of elements in the array.
According to this answer, "we have a maximum of log_2(n-1) steps" in the worst case when "element K is not present in A and smaller than all elements in A".
I think the answer to the second question is it doesn't affect the performance. Is this correct?
If you are talking worst case / big O, then you are correct - log(n) is your bound. However, if your data is fairly uniformly distributed (or you can map to that distribution), interpolating where to pick your partition can get log(log(n)) behavior. When you do the interpolation too, you also get rid of your worse cases where you have looking for one of the end elements (of course there are new pathological cases though).
For many many duplicates you might be willing to stride further away the direct center on the next probe. With more dups, you get a better margin for guessing correctly. While always choosing the half-way point gets you there in good time, educated guesses might get you some really excellent average behavior.
When I interview, I like to hear those answers, both knowledge of the book and what the theoretical is, but also what things can be done to specialize to the given situation. Often these constant factors can be really helpful (look at quicksort and its partition choosing schemes).
I don't think having duplicates matters.
You're looking for a particular number N, what matters is whether or not the current node matches N.
If I'm looking for the number 1 in the list 1-2-3-4-5-6 the performance would be identical to searching the list 1-9-9-9-9-9.
If the number N is duplicated then you will have a chance of finding it a couple steps sooner. For example if the same search was done on the list 1-1-1-1-1-9.
This is an interview question that I recently found on Internet:
If you are going to implement a function which takes an integer array as input and returns the maximum, would you use bubble sort or merge sort to implement this function? What if the array size is less than 1000? What if it is greater than 1000?
This is how I think about it:
First, it is really weird to use sorting to implement the above function. You can just go through the array once and find the max one.
Second, if have to make a choice between the two, then bubble sort is better - you don't have to implement the whole bubble sort procedure but only need to do the first pass. It is better than merge sort both in time and space.
Are there any mistakes in my answer? Did I miss anything?
It's a trick question. If you just want the maximum, (or indeed, the kth value for any k, which includes finding the median), there's a perfectly good O(n) algorithm. Sorting is a waste of time. That's what they want to hear.
As you say, the algorithm for maximum is really trivial. To ace a question like this, you should have the quick-select algorithm ready, and also be able to suggest a heap datastructure in case you need to be able to mutate the list of values and always be able to produce the maximum rapidly.
I just googled the algorithms. The bubble sort wins in both situations because of the largest benefit of only having to run through it once. Merge sort can not cut any short cuts for only having to calculate the largest number. Merge takes the length of the list, finds the middle, and then all the numbers below the middle compare to the left and all above compare to the right; in oppose to creating unique pairs to compare. Meaning for every number left in the array an equal number of comparisons need to be made. In addition to that each number is compared twice so the lowest numbers of the array will most likely get eliminated in both of their comparisons. Meaning only one less number in the array after doing two comparisons in many situations. Bubble would dominate
Firstly I agree with everything you have said, but perhaps it is asking about knowing time complexity's of the algorithms and how the input size is a big factor in which will be fastest.
Bubble sort is O(n2) and Merge Sort is O(nlogn). So, on a small set it wont be that different but on a lot of data Bubble sort will be much slower.
Barring the maximum part, bubble sort is slower asymptotically, but it has a big advantage for small n in that it doesn't require the merging/creation of new arrays. In some implementations, this might make it faster in real time.
only one pass is needed , for worst case , to find maximum u just have to traverse the whole array , so bubble would be better ..
Merge sort is easy for a computer to sort the elements and it takes less time to sort than bubble sort. Best case with merge sort is n*log2n and worst case is n*log2n. With bubble sort best case is O(n) and worst case is O(n2).
I have n numbers. n <= 1000000. Each number will be positive integer and less than 10^9.
It is sure that there will be only one number will occur once, rest will occur twice or even number of times.
The shortest solution I know is the result of XOR of all numbers. I want to know
What will be the complexity of the standard XOR solution.
How can we optimize the solution.
XORing all the numbers will be of O(n) complexity, since you'll need to visit each element only once.
I can't think of any way to optimize this further, given your requirements. XOR is a very cheap operation, and the nature of the problem requires you to visit each element at least once: otherwise, you cannot possibly know which value is unique.
The XOR algorithm is the right algorithm and the fastest one. The slow part is the way that you are reading the input.
For instance, scanf in C is slower than handrolling your own number algorithm with getchar (or even better getchar_unlocked). On the SPOJ problem that you mentioned, I got an improvement from 1.35s to 0.14s just by making this change. I'm sure that the remaining 0.04 to get the best time on the site is just due to better low-level IO than my code.
You can go for hashing. A raw solution would be to use the unique number as a key to your hash table. If that is possible, then you can probably use the hashing algorithm. A simple example is to use the numbers as an index in an array. Now, the space will be too much (I mean too too much), but can be optimized further.
I have an array of unique integers (e.g. val[i]), in arbitrary order, and I would like to populate another array (ord[i]) with the the sorted indexes of the integers. In other words, val[ord[i]] is in sorted order for increasing i.
Right now, I just fill in ord with 0, ..., N, then sort it based on the value array, but I am wondering if we can be more efficient about it since ord is not populated to begin with. This is more of a question out of curiousity; I don't really care about the extra overhead from having to prepopulate a list and then sort it (it's small, I use insertion sort). This may be a silly question with an obvious answer, but I couldn't find anything online.
In terms of time complexity, there can't be a faster method than sorting. If there was, then you could use it to sort faster: Generate the indices and then use them to reorder the original array to be in sorted order. This reordering would take linear time, so overall you would have a faster sort algorithm, creating a contradiction.
insertion sort is iirc pretty low c so works ok on small lists (its also good for almost sorted lists) however are you sure your list is small enough that a sort with better worst case complexity wouldnt be better? a non-in-place merge or quick sort would seem to fit the bill well (a quick sort may well devolve to another sort for very small lists anyway as an optimization).
ultimately to know which is quicker you will have to profile, big O only tells you how complexity grows as n -> infinity