CSC 383 Lecture Notes
Introduction to Algorithm Analysis
The plot graphs on page 34 of the book provide helpful visualizations of how fast these functions grow in relation to one another.
Function Name Goodness O(c) or O(1) Constant Best O(log N) Logarithmic Very good O(log2 N) or O(log log N) Log-squared Very good O(N) Linear Generally good O(N log N) Decent, particularly for sorting O(N2) Quadratic OK, but we'd prefer something better O(N3) Cubic Ditto O(Nk) Polynomial Not so good, but we can live with it if we have to O(2N), O(XN), O(N!) Exponential Bad news
for (i = 0; i < N; i++) { ... }
is O(N), assuming that the body does not break
out of the loop. for (i = 0; i < N; i++) {
for (j = 0; j < N; i++) { ... }
}
is O(N2); (think about why this
is the case).
for (i = 0; i < N; i++) { ... }
for (i = 0; i < N; i++) { ... }
for (i = 0; i < N; i++) {
for (j = 0; j < N; i++) { ... }
}
is O(N2) overall, since O(N) + O(N) +
O(N2) = O(N2) /**
* Return the position in the given numbers array of the first occurrence of
* the given numeric value. Return -1 if the element is not in the array
* or if the array is null.
*/
public int searchArray(int[] numbers, int value) {
int i; // Array index
/*
* Return -1 if the array is null.
*/
if (numbers == null) {
return -1;
}
/*
* Loop through the array, comparing the input value with each
* element. Return the index of the first element that equals the
* value, if any.
*/
for (i = 0; i < numbers.length; i++) {
if (numbers[i] == value) {
return i;
}
}
return -1;
}
which equals(1 + 2 + 3 + ... + N) / N
S i / N
i=1 to N
N
S i = (N (N+1)) / 2
i=1
which reduces to 1 = 1.
1
S i = (1 (1+1)) / 2
i=1
and prove
N
S i = (N (N+1)) / 2
i=1
Working from the summation side of the equation, we have
N+1
S i = ((N+1) (N+1+1)) / 2
i=1
= (N (N+1)) / 2 + N + 1 , by the inductive hypothesis
N
S i + N+1 , by the definition of summation
i=1
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
public class TestprobRelPrime
{
public static void main( String [ ] args )
{
BufferedReader in = new BufferedReader( new
InputStreamReader( System.in ) );
int x;
String oneLine;
System.out.println( "Enter an integer: " );
try
{
oneLine = in.readLine( );
x = Integer.parseInt( oneLine );
long start = System.currentTimeMillis() ;
double prob = probRelPrime(x) ;
long end = System.currentTimeMillis() ;
System.out.println( "The probability of two numbers less than " + x + " are relative prime is " + prob );
System.out.println("The running time = " + (end - start) + " miliseconds") ;
}
catch( IOException e )
{ System.out.println( e ); }
catch( NumberFormatException e )
{ System.out.println( e ); }
}
public static int gcd( int m, int n )
{
if ( m < n ) return gcd(n,m) ;
if ( n == 0 ) return m ;
if ( n == 1 ) return 1 ;
return gcd(n, m%n) ;
}
public static double probRelPrime(long n)
{
int rel = 0 , tot = 0 ;
for ( int i = 1 ; i <= n ; i++ )
for ( int j = i+1 ; j <= n ; j++ ) {
tot++ ;
if ( gcd(i,j) == 1 ) rel++ ;
}
return (double) rel / tot ;
}
}
static private int seqStart = 0;
static private int seqEnd = -1;
public static int maxSubSum1( int [ ] a )
{
int maxSum = 0;
for( int i = 0; i < a.length; i++ )
for( int j = i; j < a.length; j++ )
{
int thisSum = 0;
for( int k = i; k <= j; k++ )
thisSum += a[ k ];
if( thisSum > maxSum )
{
maxSum = thisSum;
seqStart = i;
seqEnd = j;
}
}
return maxSum;
}
public static int maxSubSum2( int [ ] a )
{
int maxSum = 0;
for( int i = 0; i < a.length; i++ )
{
int thisSum = 0;
for( int j = i; j < a.length; j++ )
{
thisSum += a[ j ];
if( thisSum > maxSum )
{
maxSum = thisSum;
seqStart = i;
seqEnd = j;
}
}
}
return maxSum;
}
public static int maxSubSum3( int [ ] a )
{
int maxSum = 0;
int thisSum = 0;
for( int i = 0, j = 0; j < a.length; j++ )
{
thisSum += a[ j ];
if( thisSum > maxSum )
{
maxSum = thisSum;
seqStart = i;
seqEnd = j;
}
else if( thisSum < 0 )
{
i = j + 1;
thisSum = 0;
}
}
return maxSum;
}
/**
* Finds maximum sum in subarray spanning a[left..right].
* Does not attempt to maintain actual best sequence.
*/
private static int maxSumRec( int [ ] a, int left, int right )
{
int maxLeftBorderSum = 0, maxRightBorderSum = 0;
int leftBorderSum = 0, rightBorderSum = 0;
int center = ( left + right ) / 2;
if( left == right ) // Base case
return a[ left ] > 0 ? a[ left ] : 0;
int maxLeftSum = maxSumRec( a, left, center );
int maxRightSum = maxSumRec( a, center + 1, right );
for( int i = center; i >= left; i-- )
{
leftBorderSum += a[ i ];
if( leftBorderSum > maxLeftBorderSum )
maxLeftBorderSum = leftBorderSum;
}
for( int i = center + 1; i <= right; i++ )
{
rightBorderSum += a[ i ];
if( rightBorderSum > maxRightBorderSum )
maxRightBorderSum = rightBorderSum;
}
return max3( maxLeftSum, maxRightSum,
maxLeftBorderSum + maxRightBorderSum );
}
/**
* Return maximum of three integers.
*/
private static int max3( int a, int b, int c )
{
return a > b ? a > c ? a : c : b > c ? b : c;
}
// an efficient exponentiation computation algorithm
public class Fig02_11
{
public static boolean isEven( int n )
{
return n % 2 == 0;
}
/* START: Fig02_11.txt*/
public static long pow( long x, int n )
{
/* 1*/ if( n == 0 )
/* 2*/ return 1;
/* 3*/ if( n == 1 )
/* 4*/ return x;
/* 5*/ if( isEven( n ) )
/* 6*/ return pow( x * x, n / 2 );
else
/* 7*/ return pow( x * x, n / 2 ) * x;
}
/* END */
// Test program
public static void main( String [ ] args )
{
System.out.println( "2^21 = " + pow( 2, 21 ) );
System.out.println( "2^50 = " + pow( 2, 50 ) );
}
}
Note : For the worst case, number of multiplications is < 2 log N .
Example : The number of multiplications required in the computation of X62