There is an array where except one number (say magic-number) all are unique. The magic-number
repeats itself more than half times the size of the array. e.g. 2, 10, 10, 10, 3. Find the magic-number without
using any extra-space and without sorting it. Now is there any method to do it in O(n).
Check each element against its neighbors, if any are equal then you have found the number. O(N)
If the first test did not find the number, then you in the following situation:
10,2,10,3,10.
In this case, the first number in the array is the magic number. O(1)
Related
We know about an algorithm that will find the Longest Increasing subsequence in O(nlogn). I was wondering whether we can find the Longest non-decreasing subsequence with similar time complexity?
For example, consider an array : (4,10,4,8,9).
The longest increasing subsequence is (4,8,9).
And a longest non-decreasing subsequence would be (4,4,8,9).
First, here’s a “black box” approach that will let you find the longest nondecreasing subsequence using an off-the-shelf solver for longest increasing subsequences. Let’s take your sample array:
4, 10, 4, 8, 9
Now, imagine we transformed this array as follows by adding a tiny fraction to each number:
4.0, 10.1, 4.2, 8.3, 9.4
Changing the numbers this way will not change the results of any comparisons between two different integers, since the integer components have a larger magnitude difference than the values after the decimal point. However, if you compare the two 4s now, the latter 4 compares bigger than the previous one. If you now find the longest nondecreasing subsequence, you get back [4.0, 4.2, 8.3, 9.4], which you can then map back to [4, 4, 8, 9].
More generally, if you’re working with an array of n integer values, you can add i / n to each of the numbers, where i is its index, and you’ll be left with a sequence of distinct numbers. From there running a regular LIS algorithm will do the trick.
If you can’t work with fractions this way, you could alternatively multiply each number by n and then add in i, which also works.
On the other hand, suppose you have the code for a solver for LIS and want to convert it to one that solves the longest nondecreasing subsequence problem. The reasoning above shows that if you treat later copies of numbers as being “larger” than earlier copies, then you can just use a regular LIS. Given that, just read over the code for LIS and find spots where comparisons are made. When a comparison is made between two equal values, break the tie by considering the later appearance to be bigger than the earlier one.
I think the following will work in O(nlogn):
Scan the array from right to left, and for each element solve a subproblem of finding a longest subsequence starting from the given element of the array. E.g. if your array has indices from 0 to 4, then you start with the subarray [4,4] and check what's the longest sequence starting from 4, then you check subarray [3,4] and what's the longest subsequence starting from 3, next [2,4], and so on, until [0,4]. Finally, you choose the longest subsequence established in either of the steps.
For the last element (so subarray [4,4]) the longest sequence is always of length 1.
When in the next iteration you consider another element to the left (e.g., in the second step you consider the subarray [3,4], so the new element is element with the index 3 in the original array) you check if that element is not greater than some of the elements to its right. If so, you can take the result for some element from the right and add one.
For instance:
[4,4] -> longest sequence of length 1 (9)
[3,4] -> longest sequence of length 2 (8,9) 1+1 (you take the longest sequence from above which starts with 9 and add one to its length)
[2,4] -> longest sequence of length 3 (4,8,9) 2+1 (you take the longest sequence from above, i.e. (8,9), and add one to its length)
[1,4] -> longest sequence of length 1 (10) nothing to add to (10 is greater than all the elements to its right)
[0,4] -> longest sequence of length 4 (4,4,8,9) 3+1 (you take the longest sequence above, i.e. (4,8,9), and add one to its length)
The main issue is how to browse all the candidates to the right in logarithmic time. For that you keep a sorted map (a balanced binary tree). The keys are the already visited elements of the array. The values are the longest sequence lengths obtainable from that element. No need to store duplicates - among duplicate keys store the entry with largest value.
How to make pairs of a sorted array such that the addition on the pairs after by multiplying of a pair is highest?
for example:
input array A[6,3,2,5]
output: (6 * 5)+(3 * 2)=36
You can achieve maximum product by multiplying the first two largest numbers. In the example you have given, A[6, 3, 2, 5]. The two largest number are 6 and 5. Therefore the maximum product that can be achieved by picking any two numbers from the array is 6*5 = 30.
I can help more if you may give more examples and show how to do the pairing in inputs of larger size. Describe your question a bit more.
I have 2 sorted integer lists or arrays a and b, both having same number of elements. I want to pair an element in a with an element in b such that when I take smaller element in all pairs, their sum is minimum.
For example,
a=[1,7,14,18]
b=[8,9,10,12]
I would be pairing [(1,12),(7,10),(14,9),(18,8)] and then taking smaller element in each pair, namely, [1,7,9,8], I will get minimum sum. This is just one possibility I took. I want to know if this method of pairing elements of first list from the first element and moving forward with elements of the second list starting from end and going backwards will give me the minimum sum.
Yes, that method of pairing the largest with the smallest will work:
If the largest element in the second array is smaller than the smallest in the first array, any pairing method will work and so pair the remaining elements using your method.
If not, pairing the first pair with your method will ensure the smallest from the first (which should be counted) will be counted and the largest from the second (which should not be counted) will not be counted
Repeat steps 1 and 2 with the remaining elements from both arrays until you run out of elements
As you can see, the smallest remaining elements from the arrays will always be counted at each step along the way, and so the sum of the smallest from the resulting pairs will be minimized as desired.
There are 2 variations of this question.
Given 2 arrays of integers, select single element from each array so that their sum is least away (numerically) from given integer value V. Sum can be greater than V.
Given 3 arrays of integers, select single element from each array so that their sum is least away (numerically) from given integer value V. Sum can be greater than V.
I know there is a naive O(n^2) and O(n^3) solution respectively for them and I'd like to ask if there's any approach which optimises running time.
For the first case, you could sort both the arrays in O(nlogn), and then for each element x in the first array, find V-x in the second array using the binary-search/upper-bound algorithm.
Its total complexity would still be O(nlogn) which is less than O(n*n).
For the second case, you can apply a similar algorithm with O(n*n*log(n)) complexity.
We have an array of N numbers. All the numbers are between 1-k.
The problem is how to find the best way of finding the most frequent triplet.
My approach to the problem is:
Say if the input is like { 1, 2, 3, 4, 1, 2, 3, 4}
First search for the count of triplet ( 1, 2, 3) start from the second element in the array till the end of the array. Now we will have the count as 1.
Now start with { 2, 3, 4) and search the array.
for each triplet we scan the array and find the count. Like this we run the array for n-1 times.
This way my algorithm runs in the order of n*n time complexity. Is there any better way for
this problem.?
You can do it in O(n * log n) worst-case space and time complexity: Just insert all triples into a balanced binary search tree and find the maximum afterwards.
Alternatively, you can use a hash table to get O(n) expected time (which is typically faster than the search tree approach in reality, if you choose a good hash function).
Are there any memory boundaries i.e. does it run on a device with memory limitations?
If not, maybe this could be good solution: iterate over array and for each tripple build and representation object (or struct if implemented in c#) which goes into map as a key and the tripple counter as a value.
If you implement hash and equals functions appropriately, you will be able to find the "most popular" tripple where numbers order matters or not e.g. 1,2,3 != 2,1,3 or 1,2,3 == 2,1,3
After iterating entire array you would have to find the largest value and its key would be your "most popular" tripple. With that approach you could find X most popular tripples too. Also you would scan array only once and aggregate all the trippels (no extra scanning for each tripple).