Adder Algorithm for n 1-bit numbers [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
suppose adding two numbers with a and b bits can be done in O(max{a,b}). we want to add n numbers (n 1-bit numbers i.e add n's 0 or 1). the cost of this algoithm is vary from input permutation to another permutation. what is the best and worst case of this algorithm?
i ran into this problem as an old- quiz on Computer Course.
We have two Solution:
1- Best Case and Worst Case can be in O(n)
2- Best in O(n) and Wost Case in O(n lg n)
Anyone could describe any pesudocode or algorithm for above two time order?

Answer is 1- Best and worst case it is O(n).
Best case, when all bits are 0, the order required is n - 1 or simply put O(n).
Worst case, when all bits are 1, the actual order is sum of n * (lg n - lg i) / 2 ^ (lg n - lg i)
i from n to 0. As i tends to 0, the resulting expression value will be small and so can be ignored. So the expression is like n/2 + n/4 * 2 + .... Again a linear growth with n.
Adding more details:
Best case, when all bits are 0, adding them will never result in a no having more than 1 digit. (ie it always gives 0). therefore the order is O(n)
Worst case, when all bits are 1, adding first 2 bit will require O(1) The result will be 10. Now adding it with another bit will require O(2) and this way order can increase in case of worst case. Assume we split the input set into 2 number pairs and add them, in the first iteration all pairs would require O(1) and will result in 10. There are n/2 pairs so it is O(n/2). In the second iteration, we split the first iteration result set into 2 number pairs and add them. (Note now all nos are 10) So the order would be n/4 * O(2). i.e, O(n/2). In this way it is to be proceeded till the result set is exhausted. But when the value of n is very large, the contribution from 3 iteration onward can be ignored. So it just O(n/2) + O(n/2) , i.e O(n)

Related

What is the time complexity of the code (generating permutations) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
Please see the code at the link below:
https://stackoverflow.com/a/20614037/1676147
My thoughts:
Time complexity here would depend on two factors:
1) Number of recursive calls: O(n) where n is the number of characters in the original input string
2) The work involved in the two for loops: O(n!)?
Basically, the first for loop is iterating each string in the set 'permSet'
The number of permutations for an n-character string can be n!.
Thus, this set would contain n! strings. Correct?
The second for loop places one character (variable 'a' in the code) at each
of the potential positions in each of these strings.
I am confused at this step.
Your analysis is correct. For a string of length N, you have N-1 recursions, with string length of M, one each for lengths 1 through N-1. Each recursion deals with a list of size (M-1)!, and inserts the next character at each of M positions (0 through M-1).
Each call has time M * (M-1)!, or M! Sum these over M = 1 to N.
1! + 2! + 3! + ... + N!
This sum is O(n!).

Running time between Linked List and ArrayList? Code analysis

I have a midterm next week, and some of it has to do with code analysis/ sum simplification. I'm very lost, and am trying to understand this question my professor gave us on a practice work sheet.
Here is the pseudo code:
List <Integer> method( List <Integer> ints) {
for ( int i = 0; i < ints.size() / 2; i ++) {
swap(i, n − i − 1);
}
The question is asking: Express the worst case running time of this method as a sum assuming that the List is an ArrayList?
In which I got O(log n), since the size of the list is being divided in half every time.
But then the next question is: Express the worst case running time of this method as a sum assuming that the List is an LinkedList?
Now I am confused, I know that ArrayLists and LinkedLists have different time complexities, but wouldn't the answer be the same O(log n)?
Also how would I express this as a sum for each question? This is not homework, but I am trying my best to understand this subject.
If ints is an ArrayList, it can access any element in constant time. So it is going through the first half of the elements and swapping them with the corresponding element from the second half. This is still considered to be O(n) because the total number of iterations will be 1/2 * (n), and you drop the constant for the big O notation.
If ints is a LinkedList, you do not have constant time access to any element- you have to traverse the entire list to get to each element. So for each element in the first half of the list, you are iterating through again to find the corresponding element from the second half. This leads to a worst case runtime of O(n^2).

Deciding a Big-O notation for an algorithm

I have questions for my assignment.
I need to decide what is the Big-O characterization for this following algorithm:
I'm guessing the answer for Question 1 is O(n) and Question 2 is O(log n), but I kinda confused
how to state the reason. Are my answers correct? And could you explain the reason why the characterization is like that?
Question 1 : O(n) because it increments by constant (1).
first loop O(n) second loop also O(n)
total O(n) + O(n) = O(n)
Question 2 : O(lg n) it's binary search.
it's O(lg n), because problem halves every time.
if the array is size n at first second is n/2 then n/4 ..... 1.
n/2^i = 1 => n = 2^i => i = log(n) .
Yes, your answers are right.The first one is pretty simple. 2 separate for loops. So effectively its O(n).
The second one is actually tricky. You are actually dividing the input size by 2 (half), that would effectively lead to a time complexity of O(log n).

Counting sort and usage in Java applications [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I did an algoritms refresher and I (re)read about a sorting algorithm that runs in linear time, namely Counting Sort.
To be honest I had forgotten about it.
I understand the structure and logic and the fact that it runs in linear time is a very attactive quality.
But I have the folowing question:
As I understanding the concrete implementation of the algorithm relies on 2 things:
1) The range of input numbers is small (otherwise the intermediate array will be huge and with many gaps).
2) We actually know the range of numbers.
Taking that these 2 assumptions are correct (please correct me otherwise), I was wondering what is the best application domain that this algorithm applies to.
I mean specifically in Java, is an implementation like the following Java/Counting sort sufficient:
public static void countingSort(int[] a, int low, int high)
{
int[] counts = new int[high - low + 1]; // this will hold all possible values, from low to high
for (int x : a)
counts[x - low]++; // - low so the lowest possible value is always 0
int current = 0;
for (int i = 0; i < counts.length; i++)
{
Arrays.fill(a, current, current + counts[i], i + low); // fills counts[i] elements of value i + low in current
current += counts[i]; // leap forward by counts[i] steps
}
}
or it is not a trivial matter to come up with the high and low?
Is there a specific application in Java that counting sort is best suited for?
I assume there are subtleties like these otherwise why would anyone bother with all the O(nlogn) algorithms?
Algorithms are not about the language, so this is language-agnostic. As you have said - use counting sort when the domain is small. If you have only three numbers - 1, 2, 3 it is far better to sort them with counting sort, than a quicksort, heapsort or whatever which are O(nlogn). If you have a specific question, feel free to ask.
It is incorrect to say counting sort is O(n) in the general case, the "small range of element" is not a recommendation but a key assumption.
Counting sort assumes that each of the elements is an integer in the
range 1 to k, for some integer k. When k = O(n), the Counting-sort
runs in O(n) time.
In the general situation, the range of key k is independent to the number of element n and can be arbitrarily large. For example, the following array:
{1, 1000000000000000000000000000000000000000000000000000000000000000000000000000}
As for the exact break even point value of k and n where counting sort outperform traditional sort, it is hugely dependent on the implementation and best done via benchmarking (trying both out).

How does one output a new array, containing all numbers of a previous array that occur at most k times

How does one create a new array, containing all numbers of the array that occur at most k times in java?
For example, if the array was:
{1,4,4,3,4,3,5,2,5,1,5}
and k = 2, the new array would be:
{1,3,2}.
I assume that I would need to compare the elements within the arrays and add store the number of times it occurs as a variable. Then I would compare that variable to k and if it is smaller or equal to it, it will add it to a new arraylist. I can't really implement this tho.
Thanks
There are many ways to do this, depending on what your constraints are.
If you don't need to worry about memory constraints, you can solve this problem quite easily by using a HashMap that maps from array elements to their frequencies. The algorithm would work by scanning across the array. For each element, if that element is already in the HashMap, you update the key/value pair in the HashMap to increment the frequency of that element. Otherwise, if the element hasn't been seen, you update the frequency to be 1. Once you've finished populating the HashMap, you can then iterate across the map and copy over all elements that have frequency at most k into a new ArrayList. For example:
for(Map.Entry<T, Integer> entry: myMap.entrySet()) {
if (entry.getValue() <= k)
myArrayList.add(entry.getKey());
}
This runs in O(n) time and O(n) memory, which is quite good.
If you don't want to store everything in memory, another option would be to sort the array in O(n log n) time and O(log n) space using Arrays.sort. Once you've sorted the array, all of the copies of each value will be stored consecutively and you can more easily count their frequency. For example, after sorting the array you mentioned in your original post, you would get the array
1 1 2 3 3 4 4 4 5 5 5
From here, it should be much easier to determine how many copies of each element there are. You could do this by walking across the array, keeping track of the element you're currently looking for and how many copies there are. Whenever you see a new element, if it matches the current element, you increment the counter. If not, you reset the element you're checking to be the new element and set the counter back to one. For example, with the above array, you might start off by looking at this element:
1 1 2 3 3 4 4 4 5 5 5
^
Element: 1
Frequency: 1
Now, you look at the next element of the array. Because it's a 1, you increment the frequency count to 2:
1 1 2 3 3 4 4 4 5 5 5
^
Element: 1
Frequency: 2
When you look at the next element, you'll see that it's a 2. This means that there aren't any more 1's left. Because there are two copies of 1, you could then append 1 to the resulting array. You'd then reset the counter to 1, leaving this state:
1 1 2 3 3 4 4 4 5 5 5
^
Element: 2
Frequency: 1
The one thing to watch out for when doing this is to remember to handle the case where you visit the final array element. It's important that when you hit the end of the array, if you have at most k copies of the last element, you add the last number to the output array.
Whenever you do this, if you ever find an element that appears at most k times, you can add it to the new array. This second step runs in O(n) time and O(m) space (where m is the total number of elements in the resulting array), so the total complexity is O(n log n) time and O(m + log n) space.
Hope this helps!
You have at least two ways to do it:
Scan linearly the array, updating an hash table which stores the frequency of each encountered number (Average time: O(n), Space: O(n));
Sort the array and keeping a count of how many times you've seen the current element (which will be set to one every time the current number is different from the previous one). Time: O(n lg n), Space: O(m), where m is the number of returned element (assuming to use a O(1) space-complexity sorter, like heapsort).
The first one is time-optimal, the second one is space-optimal.

Categories