BIG O Analysis of Loops - java

Can someone provide examples of loops that are PolynomialO O(n^2) , Exponential O(2^n) , and Factorial O(n1). I can't seem to wrap my head around it.
I understand the concepts of O(log n)for (int i=0; i<=10; i=i*2) OR for (int i=0; i<=10; i=i/2)O(n)for (int i=0; i<=10; i++)or (int i=10; i<=0; i--). O(n^2)
`
for (int i=0; i<=10; i++)
{
for (int i=0; i<=10; i++)
{
//DO SOMETHING
}
}

A more obviously O(2^N) example is:
public int count2PowerN(int n) {
if (n <= 1) {
return n;
} else {
return count2PowerN(n - 1) + count2PowerN(n - 1);
}
}
Notes:
O(2^N) is equivalent to any O(c^N) where c is a constant. It is conventional to use e as the nominal constant; i,e O(e^N)
you cannot get super-polynomial complexity with simple nested loops. You need either recursion or a dynamic data structure.

O(n^2):
int count = 0;
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
count++;
}
}
This is pretty simple, for every nested loop you will increase your power. So if you had 3 for loops instead of two, then it would be O(n^3)
O(2^n):
public int fibonacci(int n){
if (n<= 1) return n;
return fibonacci(n- 2) + fibonacci(n- 1);
}
For every iteration of this method, two other "branches" will be created (until n<=1) since it has two recursive calls. So the growth doubles for every iteration.
O(n!):
public int factorialRuntime(int n) {
int count = 0;
for(int i=0; i<n; i++) {
count += factorialRuntime(n-1);
}
return count;
}
This example was pulled from here.

Related

Is there a way to scan an one-dimension array for an SVD so you can have complexity of O(n)?

I am trying to scan an one-dimensional array for Singular Value Decomposition(SVD) and the worst time and space complexity to be O(n) without using any secondary data structure.
They only way I manage to do it is with a nested loop, but that is making it O(n^2)
public static void svd(Integer[] array){
int count = 0;
int svd = 0;
for (int i = 0; i < array.length; i++) {
count=0;
for (int j = 0; j < array.length; j++) {
if(array[i] == array[j]){
count++;
}
if(count>(array.length/2)){
svd = array[i];
System.out.println("svd = "+svd);
}
else if(count<array.length/2){}
}
}
}
The awnser is using the Boyer-Moore majority vote algorithm
https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm

Is this the correct way of doing bubble sort?

just wondering whether this is the correct way of doing a Bubble Sort algorithm. I found this in the internet the way of doing Bubble sort but I didn't get the logic of this algorithm, this is the algorithm from a website:
int n = arr.length;
int temp = 0;
for(int i=0; i < n; i++)
{
for(int j=1; j < (n-i); j++)
{
if(arr[j-1] > arr[j])
{
//swap elements
temp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = temp;
}
}
I understand that you need nested loops in Bubblesort however the part I don't understand is why you need
for(int j=1; j < (n-i); j++){
if(arr[j-1] > arr[j])
Why is "n minus 1" needed or "j minus 1 needed", can't you just have two exact for loops like for(int i=0; i < n; i++) and for(int j=0; j < n; j++)
as a nested loop? Can anybody give me a visual layman's term explanation why this is.
Hence I have produced a Bubble sort Algorithm with two exact same nested loops.
But I don't know whether it is alright. Here is the code:
import java.lang.Math; // headers MUST be above the first class
import java.util.Arrays;
// one class needs to have a main() method
public class HelloWorld
{
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
int integerArray [] = {4,6,1,3,2,8,678,122,12,29,57, -1};
int temporaryValue;
for (int i = 0; i < 11; i++) // integerArray.lenght
{
for(int j = 0; j<11; j++)
{
if (integerArray [j] > integerArray [j+1])
{temporaryValue = integerArray[j];
integerArray [j] = integerArray [j+1];
integerArray [j+1] = temporaryValue;
}
}
}
for (int j = 0; j < integerArray.length; j++)
{
System.out.print(integerArray[j]+",");
}
}
}
You need (n -i) because after each pass, you know that the greatest element is at its right position[end]. So, you don't need to perform any swap operation for this greatest element.It just reduces the number of swap operations.
You don't need (j -1). The example iterates j from index 1 to (n - i)[excluded] and you are iterating j from index 0 to (integerArray.length - 1)[excluded]
Suggestion: Take a pen and paper and execute your algorithm. You will be able to understand why we need (n -i)

Is my Bubble Sort implementation correct?

public class MyBubbleSort {
public static void bubbleSort(int[] a, int n) {
int i, j, temp;
for (i = 0; i <= (n-2); i++) {
for (j = i + 1; j <= (n-1); j++) {
if (a[j] < a[i]) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
}
It gives me a sorted array when I do a debug but I just wanted to be 100% sure.
You could tidy the code a bit:
Make it extend an interface Sort with a single method sort(int[] a, int n).
MyBubbleSort method should implement said interface and not be static.
int i and j should be declared inside the corresponding fordeclaration.
temp should be declared inside the inner if.
It is questionable if you need to pass in the length of the array as this is a property on the Java array type. The only time to pass the length would be if you intended to sort sub arrays.
You are doing a correct bubble sort ! In your "if" statement, you are correctly swapping two adjacent values if they are not well sorted. And this is the principle of the bubble sort: you repeat this process until your array is correctly sorted. https://www.youtube.com/watch?v=lyZQPjUT5B4
However you are doing strange things in your code ! As zapl said in the comments you don't need this "n" parameter as you can simply get you array's size in your method.
Also prefer using " < length ", " < length - 1 " instead of your <= which are, if you think well, more intuitive
public static void bubbleSort(int[] tab) {
int n = tab.length ;
for (int i = 0; i < n-1; i++) {
for (int j = i + 1; j < n ; j++) {
if (tab[j] < tab[i]) {
int temp = tab[i];
tab[i] = tab[j];
tab[j] = temp;
}
}
}
}

Time Complexity of the Algorithms

I have created two algorithms that calculate the prefix averages with a given array. I wanted to derive the time complexities of both algorithms, but I have been struggling a bit. I watched this YouTube video:
https://www.youtube.com/watch?v=udwxWq9wZgg&safe=active. I did not understand how to count the operations in a for loop and a nested for loop.
At 2:27, I managed to count the operations in the for loop in PrefixAverages2. It was 3n+1. However, I cannot understand from 5:50 onwards.
Thanks in advance.
public double[] PrefixAverages1(double input[])
{
double A[] = new double[input.length];
double s;
for(int i=0; i <= input.length - 1 ;i++)
{
s = input[0];
for(int j=1; j <= i ;j++)
{
s = s + input[j];
}
A[i] = s / (i+1);
}
return A;
}
public double[] PrefixAverages2(double input[])
{
double A[] = new double[input.length];
double s = 0;
for( int i=0; i <= input.length - 1 ; i++)
{
s = s + input[i];
A[i] = s / (i+1);
}
return A;
}
for(int i=0; i <= input.length - 1 ;i++)
for(int j=1; j <= i ;j++)
This is quadratic, for a given i, inner loop goes about i-times, so you have to sum over i, so basically you have something like sum_{i=1}^{i=l} i, which is the sum of the first l integers, so l(l+1)/2, then quadratic.
For the second algorithm you just have one loop so its complexity is linear.

No duplicates in an array [duplicate]

This question already has answers here:
How to get unique values from array
(13 answers)
Closed 8 years ago.
void RemoveDups(){
int f=0;
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i;k<nelems;k++)
{
arr[k]=arr[k+1];
}
nelems--;
}
if(i==(nelems+1)){
f++;
i=f+1; //increment again
}
}
}
This is the logic i have written to remove duplicate elements from an array ,but this is not working at all ?what changes i should make to make it work? or you people have better logic for doing the same considering time complexity.and i don't want to use built-in methods to achieve this.
int end = input.length;
for (int i = 0; i < end; i++) {
for (int j = i + 1; j < end; j++) {
if (input[i] == input[j]) {
int shiftLeft = j;
for (int k = j + 1; k < end; k++, shiftLeft++) {
input[shiftLeft] = input[k];
}
end--;
j--;
}
}
}
I think you can use Set Collection
copy all the values to an HashSet and then using Iterator access the Values
Set<Integer> hashset= new HashSet<Integer>();
You have two options, C# has the Distinct() Linq expression that will do this for you (Missed the Java tag), however if you need to remove items, have you thought about sorting the list first, then comparing the current item to the previous item and if they're the same, remove them. It would mean your diplicate detection is only ever running through the array once.
If you're worried about sort you could easily implement an efficient bubble sort or somthing to that effect
You never decrease i after You compared for examlpe arr[0] to arr[5], You never will test arr[1] == arr[2]
You need to start a new loop (i) after You've incremented f.
try
for(int f=0;f<nelems-1;f++)
{
for(int i=f+1;i<nelems;i++)
{
...
}
}
with this nested for loop you can compare every two element of the array.
a good start is to eliminate duplicate elements without shrinking the array which is done lastly:
public class run2 extends Thread {
public static void main(String[] args) {
int arr[] = { 1, 2, 2, 3, 5, 6, 5, 5, 6, 7 };
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] == -1)
j++;
if (arr[i] == arr[j])
arr[j] = -1;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
System.out.println();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == -1) {
for (int j = i; j < arr.length; j++) {
if (arr[j] != -1) {
arr[i] = arr[j];
arr[j] = -1;
break;
}
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
Adapt this code :
public static int[] removeDuplicates(int[] numbersWithDuplicates) {
// Sorting array to bring duplicates together
Arrays.sort(numbersWithDuplicates);
int[] result = new int[numbersWithDuplicates.length];
int previous = numbersWithDuplicates[0];
result[0] = previous;
for (int i = 1; i < numbersWithDuplicates.length; i++) {
int ch = numbersWithDuplicates[i];
if (previous != ch) {
result[i] = ch;
}
previous = ch;
}
return result;
}
As far as I understood from your code,you are comparing each value starting from index 0 to the rest of the element and when you see the element which is located at index f your are trying to shift the entire array and decrementing the size of array(nelems).Look at line no. 11
if(i==(nelems+1)){
f++;
i=f+1;
The problem is when i is set to f+1,i will again be incremented in the for loop for the next iteration.So basically i starts comparing from f+2.And also you are comparing i with (nelems+1) considering the case when nelems decremented but you are not considering the case when i reaches the end without decreasing nelems in that case i will never be equale to (nelems+1).Now considering your logic you could do 2 things.
1.Here is your working code.
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i+1;k<nelems;k++)
{
arr[k-1]=arr[k];
}
if(i==(nelems-1)){
f++;
i=f;
}
nelems--;
}
if(i==(nelems-1)){//end of the loop
f++;
i=f; //increment again
}
}
2.You could use an outer for loop alternatively that will increment the f value once the inner for is completed.
void RemoveDups(){
for(int f=0;f<nelems;++f){
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i;k<nelems;k++)
arr[k]=arr[k+1];
nelems--;
}
}
}
}
Now your problem is solved but the time complexity of your code will be(O(N^3)).
Now instead of shifting the entire array at line 4,you could just swap the arr[f] with last element.
if(arr[f]==arr[i]){
swap(arr[f],arr[nelems-1]);
nelems--;
}
it will reduce the time complexity from O(N^3) to O(N^2).
Now I'll suggest you my method
1.just sort the array.It will be done in O(NlogN).
2.now using one for loop you can get what do you wanted.
void RemoveDups(){
int k=0,i;
for(i=1;i<nelems;++i){
while(arr[i]==arr[i-1])
++i;
arr[k++]=arr[i-1];
}
arr[k++]=arr[i-1];
}
Now basically you got an array of size k,which contains non repeated element in sorted order and the time complexity of my solution is O(NlogN).

Categories

Resources