I want to calculate total number of iterations a code will take - java

This is my code for a simple selection sort.usually the complexity (time) for a sort is number of iterations it has taken for sorting O(n^2) in case of selection sort
When I dry ran this code against sample string of 98765, it gave me 25 iterations.
Just to cross check with my dry ran output i put 2 vbl- noi and noj in my code.
Q: will the number of total iterations be = noi*noj or noi+noj;
int index = 0; int noi = 0, noj = 0;
for (j = 0; j < 5; j++)
{
noj++;
index = j;
for (i = j; i < 5; i++)
{
if (a[index] > a[i])
{
a[index] = a[index] + a[i];
a[i] = a[index] - a[i];
a[index] = a[index] - a[i];
noi++;
}
}
}

number of iterations is always 15 (5+4+3+2+1) because in your loops there are j<5 and i<5. So your code complexity is O(n^0) because in your case n is 5

Complexity doesn't depend from n because there's no n. The complexity is always exactly 15 (1+2+3+4+5 as said shift66)

it is: noj [for first loop] + (( noj * (noj + 1) ) / 2) [for inner loop]
as first loops is from 1-noj and second is j-noj (where j depends on first loop)

Related

analysis of algorithm run time

What would the big-O run time be? I'm mostly confused about the while loop run time. I know the run times for both for loops are O(n).
cin >> n >> min >> max;
for(int i = min; i < n; i++) {
for(int j = 1; j < max; j++) {
total = 1;
while(total < n) {
total = total *2;
}
}
}
The progression of target in the while loop is:
1 2 4 8 ... 2^P
You need log(2, n) steps -- i.e. log of n in base 2. That loop is O(log n).
First of all, it looks like you forgot to put braces. I'm your code, as it is, the whole loop is not inside the nested for loops. As it is, we have a pointless nested for loop that just sets total to 1, followed by an independent while loop. The complexity of the first is O((n - min) * max), and the second is O(log(n)). The total time complexity is the sum of these.
Probably what you really meant is this:
for(int i = min; i<n; i++) {
for(int j =1; j< max; j++) {
total = 1;
while(total < n) {
total = total *2;
}
}
}
Here, we have the whole loop inside the nested for loops. The time complexity is the multiple of what we calculated earlier, so O((n - min) * max * log(n)). If min and max are constants, then we can reduce to O(n log n)

O(n log n) Time Complexity Algorithm?

I created this algorithm to find the best trade between 3 numbers. It goes through the program and finds the best day to sell, buy, and profit from stock. I need to explain the algorithm used and how the time complexity is O(n log n) but I have a lot of trouble determining that. I was hoping someone could explain O(n log n) and relate it to the method I have.
Here's my method:
public static Trade bestTrade(int[] a)
{
int lowest = a[0];
int lowestIndex = 0;
int highest = a[a.length - 1];
int highestIndex = a.length - 1;
int profit = 0;
for(int i = 1; i < a.length; i++)
{
if (a[i] < lowest && i < highestIndex)
{
lowest = a[i];
lowestIndex = i;
}
}
for(int i = a.length - 2; i >= 0; i--)
{
if (a[i] > highest && i > lowestIndex)
{
highest = a[i];
highestIndex = i;
}
}
for(int i = 1; i < a.length; i++)
{
if (a[i] < lowest && i < highestIndex)
{
lowest = a[i];
lowestIndex = i;
}
}
if (highestIndex > lowestIndex)
{
profit = highest - lowest;
return new Trade(lowestIndex, highestIndex, profit);
}
return new Trade(lowestIndex, highestIndex, profit);
}
}
This function is of O(n) which is superior to O(n log n) .
In general you just look at the loops, since there is no nested loops and you only have loops which go through all elements of a The function is considered n.
The complexity is O(n), where n the length of array a.
You loop 3 times over a, so the running time is roughly 3n, so it is of the order n: O(n).
Try finding the answer to this by yourself. It will help a lot in the future. Also this looks like a O(N) , I am not sure why you are convinced that it is O(NlogN).
This link might be useful,
http://pages.cs.wisc.edu/~vernon/cs367/notes/3.COMPLEXITY.html
O(n)
It is directly proportional to the number of a.length. Each time the for function is run, it runs through every day of data. If there were a method where the number of processes went up by more than the pure number (nested fors) then it could be O(n log n) or O(n^2). But in this case, it's pretty clearly just big O of n.

How to know complexity of finding kth largest element in specific implementation

I am trying to teach myself order statistics by solving the problem
find the kth largest element in an array in O(n) time.
My Java implementation is as follows below.
Qn: I am unsure of how to determine the complexity of my code. From what I understand, it does not exceed n. Is this correct? Or how should I get this?
Have adapted the algorithm from pg 215, Intro to Algo MIT Press.
package intp;
public class IntP {
public static void main(String[] args) {
int[] qn = {10,22,33,4,5,6,1};
int[] res = {0,0};
int q;
int k =3;
q=k;
while (k>=1){
res = findMax(qn,k);
qn[res[1]]=0;
k=k-1;
}
System.out.println("Largest element number "+q+ " is: "+res[0]);
}
public static int[] findMax(int[] a,int k){
int pos=0;
int max = a[0];
int[] ans= {0,0};
for(int i= 1;i<a.length;i+=2){
if (i+1==a.length){
if (a[i]>max){
max=a[i];
pos=i;
}
break;
}
if (a[i]>a[i+1] && a[i]>max){
max=a[i];
pos=i;
}
else if (a[i+1]>max && a[i+1]>max){
max= a[i+1];
pos=i+1;
}
}
ans[0]=max;
ans[1]= pos;
return ans;
}
}
First Time complexity of findMax:
Time(findMax) = 3 + 1/2 n * (4 + 2) + 1 + 3
Time(findMax) = 3 n + 7
Time(findMax) ~ n
Time(findMax) ~ O(n)
Then Time complexity of main:
Time(main) = 5 + k * (3 + Time(findMax))
Time(main) = k * (3 n + 10) + 5
Time(main) = 3 k n + 10 k + 5
Time(main) ~ k * Time(findMax)
Time(main) ~ O(kn)
Note: I considered any managed instruction as 1 operation
Repetitive selection of the maximum is a poor way to implement selection of the Kth (except maybe for very small K). It takes worst-case time O(KN).
A better approach is to sort the array, for example using Quicksort, performing in expected O(N.Lg(N)). Anyway, the worst-case time is quadratic, O(N²).
A bit better, Quickselect, a "stripped-off" version of Quicksort. Closer to linear time O(N), but it keeps the worst-case O(N²).
The truly optimal approach (in the asymptotic sense) is that of the Median of Medians, with a guaranteed O(N) behavior.
My preferred implementation of the naïve approach:
for (i= 0; i < n; i++) // Try every element a[i]
{
int r= 0;
for (j= 0; j < n; j++) // Evaluate the rank by counting inferior elements
{
r+= a[j] < a[i] || (a[j] == a[i] && j < i); // Mind the equal elements
}
if (r == k) // Desired rank
return i;
}

Complexity of finding all substrings of a string

Here is a solution for finding all substrings of a string.
for (int i = 0; i < str.length(); i++) {
String subStr;
for (int j = i; j < str.length(); j++) {
subStr = str + str.charAt(j));
System.out.println(subStr);
}
}
All over the internet I read that the complexity of this code is O(n2).
However the + operation is an O(n) operation.
Thus in my opinion the complexity should be O(n3).
In case I am wrong, please correct my understanding.
Adding a character to a string is a O(1) operation. You get O(n3) if you take into account also the time need to print the output with println.
Finding all substrings of a string is O(n2) (by finding a substring I mean determining its begin and end indexes), it's easy to see because the total number of substrings is O(n2).
But printing all of them out is O(n3), simply because total number of characters to be printed is O(n3). In your code, println adds O(n) complexity (the + operator should have O(1) complexity if used/implemented properly).
Finding all substrings from a string the naive way is indeed O(n^2). But the code in the question doesn't probably do that. Here is the corrected version.
for (int i = 0; i < str.length(); ++i) {
//Initialize with max length of the substring
StringBuilder prefix = new StringBuilder(str.length() - i);
for (int j = i; j < str.length(); ++j) {
prefix.append(str.charAt(j)); //this step is O(1).
System.out.println(prefix); //this step is supposed to be O(1)
}
}
The total number of iterations is given by
Outer Loop : Inner Loop
First time : n
Second time : n - 1
Third Time : n - 2
..
n - 2 time : 2
n - 1 time : 1
So the total number of iterations is sum of iterations of outer loop plus sum of iterations of the inner loop.
n + (1 + 2 + 3 + ... + n - 3 + n - 2 + n - 1 + n) is = O(n^2)

review of a codility test - pair_sum_even_count

I recently took an online test on codility as part of a recruitment process. I was given two simple problems to solve in 1 hour. For those who don't know codility, its an online coding test site where you can solve ACM style problems in many different languages.
If you have 30 or so mins then check this http://codility.com/demo/run/
My weapon of choice is usually Java.
So, one of the problems I have is as follows (I will try to remember, should have taken a screenshot)
Lets say you have array A[0]=1 A[1]=-1 ....A[n]=x
Then what would be the smartest way to find out the number of times when A[i]+A[j] is even where i < j
So if we have {1,2,3,4,5}
we have 1+3 1+5 2+4 3+5 = 4 pairs which are even
The code I wrote was some thing along the lines
int sum=0;
for(int i=0;i<A.length-1;i++){
for (int j=i+1;j<A.length;j++){
if( ((A[i]+A[j])%2) == 0 && i<j) {
sum++;
}
}
}
There was one more restriction that if the number of pairs is greater than 1e9 then it should retrun -1, but lets forget it.
Can you suggest a better solution for this. The number of elements won't exceed 1e9 in normal cases.
I think I got 27 points deducted for the above code (ie it's not perfect). Codility gives out a detailed assessment of what went wrong, I don't have that right now.
The sum of two integers is even if and only if they are either both even or both odd. You can simply go through the array and count evens and odds. The number of possibilities to combine k numbers from a set of size N is N! / ((N - k)! · k!). You just need to put the number of evens/odds as N and 2 as k. For this, the above simplifies to (N · (N - 1)) / 2. All the condition i < j does is to specify that each combination counts only once.
You can find the sum without calculating every pair individually.
A[i]+A[j] is even if A[i] is even and A[j] is even; or A[i] is odd and A[j] is odd.
A running total of odd and even numbers up to j can be kept, and added to sum depending on whether A[j] is odd or even:
int sum = 0;
int odd = 0;
int even = 0;
for(int j = 0; j < A.length; j++) {
if(A[j] % 2 == 0) {
sum += even;
even++;
} else {
sum += odd;
odd++;
}
}
Edit:
If you look at A={1,2,3,4,5}, each value of j would add the number of pairs with A[j] as the second number.
Even values:
A[j]=2 - sum += 0
A[j]=4 - sum += 1 - [2+4]
Odd values:
A[j]=1 - sum += 0
A[j]=3 - sum += 1 - [1+3]
A[j]=5 - sum += 2 - [1+5, 3+5]
Please check this
if (A == null || A.length < 2) {
return 0;
}
int evenNumbersCount = 0;
int oddNumberCount = 0;
for (int aA : A) {
if (aA % 2 == 0) {
evenNumbersCount++;
} else {
oddNumberCount++;
}
}
int i = (evenNumbersCount * (evenNumbersCount - 1)) / 2 + (oddNumberCount * (oddNumberCount - 1)) / 2;
return i > 1000000000 ? -1 : i;
If someone has a problem with understanding what Sante said here is another explanation:
Only odd+odd and even+even gives even. You have to find how many even and odd numbers are there. When you have it imagine that this as a problem with a meeting. How many people distinkt pairs are in the odd numbers list and even numbers list. This is the same problem as how many pairs will say hallo to each other at the party. This is also the number of edges in full graph. The answer is n*(n-1)/2 because there are n people, and you have to shake n-1 peoples hands and divide by 2 because the other person cant count your shake as distinct one. As you have here two separate "parties" going on you have to count them independently.
It's very simple
First you need to find the number of odds and even number in collection.
eg. x is odd if x&1 ==1, even otherwise,
if you have this, knowing that adding two even or two odds to each you get even.
You need to calc the sum of Combinations of two elements from Even numbers and Odd numbers.
having int A[] = {1,2,3,4,5};
int odds=0, evens=0;
for (int i=0; i< A.length; ++i)
{
if (A[i]&1==1) odds++;
else evens++;
}
return odds*(odds-1)/2 + evens*(evens-1)/2;
// Above goes from fact that the number of possibilities to combine k numbers from a set of size N is N! / ((N - k)! · k!). For k=2 this simplifies to (N · (N - 1)) / 2
See this answer also
int returnNumOFOddEvenSum(int [] A){
int sumOdd=0;
int sumEven=0;
if(A.length==0)
return 0;
for(int i=0; i<A.length; i++)
{
if(A[i]%2==0)
sumEven++;
else
sumOdd++;
}
return factSum(sumEven)+factSum(sumOdd);
}
int factSum(int num){
int sum=0;
for(int i=1; i<=num-1; i++)
{
sum+=i;
}
return sum;
}
public int getEvenSumPairs(int[] array){
int even=0;
int odd=0;
int evenSum=0;
for(int j=0; j<array.length; ++j){
if(array[j]%2==0) even++;
else odd++;
}
evenSum=((even*(even-1)/2) + (odd *(odd-1)/2) ;
return evenSum;
}
A Java implementation that works great based on the answer by "Svante":
int getNumSumsOfTwoEven(int[] a) {
long numOdd = 0;
long numEven = 0;
for(int i = 0; i < a.length; i++) {
if(a[i] % 2 == 0) { //even
numOdd++;
} else {
numEven++;
}
}
//N! / ((N - k)! · k!), where N = num. even nums or num odd nums, k = 2
long numSumOfTwoEven = (long)(fact(numOdd) / (fact(numOdd - 2) * 2));
numSumOfTwoEven += (long)(fact(numEven) / (fact(numEven - 2) * 2));
if(numSumOfTwoEven > ((long)1e9)) {
return -1;
}
return numSumOfTwoEven;
}
// This is a recursive function to calculate factorials
long fact(int i) {
if(i == 0) {
return 1;
}
return i * fact(i-1);
}
Algorithms are boring, here is a python solution.
>>> A = range(5)
>>> A
[0, 1, 2, 3, 4]
>>> even = lambda n: n % 2 == 0
>>> [(i, j) for i in A for j in A[i+1:] if even(i+j)]
[(0, 2), (0, 4), (1, 3), (2, 4)]
I will attempt another solution using vim.
You can get rid of the if/else statement and just have the following:
int pair_sum_v2( int A[], int N ) {
int totals[2] = { 0, 0 };
for (int i = 0; i < N; i++ ) {
totals[ A[i] & 0x01 ]++;
}
return ( totals[0] * (totals[0]-1) + totals[1] * (totals[1]-1) ) / 2;
}
Let count odd numbers as n1 and count even numbers as n2.
The sum of Pair(x,y) is even, only if we choose both x and y from the set of even numbers or both x and y from odd set (selecting x from even set and y from odd set or vice-versa will always result in the pair's sum to be an odd number).
So total combination such that each pair's sum is even = n1C2 + n2C2.
= (n1!) / ((n1-2)! * 2!) + (n2!) / ((n2-2)! * 2!)
= (n1 * (n1 - 1)) / 2 + (n2 * (n2 - 1)) / 2
--- Equation 1.
e.g : let the array be like: {1,2,3,4,5}
number of even numbers = n1 = 2
number of odd numbers = n2 = 2
Total pair such that the pair's sum is even from equation: 1 = (2*1)/2 + (3*2)/2 = 4
and the pairs are: (1,3), (1,5), (2,4), (3,5).
Going by traditional approach of adding and then checking might result in an integer overflow in programming on both positive as well as on negative extremes.
This is some pythonic solution
x = [1,3,56,4,3,2,0,6,78,90]
def solution(x):
sumadjacent = [x[i]+x[i+1] for i in range(len(x)-1) if x[i] < x[i+1]]
evenpairslist = [ True for j in sumadjacent if j%2==0]
return evenpairslist
if __name__=="__main__":
result=solution(x)
print(len(result))
int total = 0;
int size = A.length;
for(int i=0; i < size; i++) {
total += (A[size-1] - A[i]) / 2;
}
System.out.println("Total : " + total);

Categories

Resources