[Data structure] Calculation of time complexity and space complexity

Table of contents

algorithmic complexity

time complex concept

Time Complexity Calculation Method

Asymptotic notation for big O

The concept of spatial complexity

Computational Methods for Space Complexity

Applications of Time and Space Complexity

disappearing numbers

rotation array


algorithmic complexity

After the algorithm is written into an executable program, it needs to consume time resources and space (memory) resources when running. Therefore, to measure the quality of an algorithm, it is generally measured from two dimensions of time and space , as well as time complexity and space complexity.

Time complexity mainly measures the running speed of an algorithm, while space complexity mainly measures the extra space required for an algorithm to run. In the early days of computer development, computers had very little storage capacity. So I am very concerned about the space complexity. However, with the rapid development of the computer industry, the storage capacity of computers has reached a very high level. So we no longer need to pay special attention to the space complexity of an algorithm.
 

time complex concept

Definition of Time Complexity: In computer science, the time complexity of an algorithm is a function that quantitatively describes the running time of that algorithm. The time it takes for an algorithm to execute, theoretically, cannot be calculated, and you can only know it if you put your program on the machine and run it. But do we need to test each algorithm on the computer? It is possible to test all algorithms on the computer, but it is very troublesome, so the analysis method of time complexity is used. The time spent by an algorithm is proportional to the number of executions of the statements in it, and the number of executions of the basic operations in the algorithm is the time complexity of the algorithm.


Namely: finding the mathematical expression between a certain basic query and the problem size N is to calculate the time complexity of the algorithm.

Time Complexity Calculation Method

Please calculate how many times the ++count statement in Func1 has been executed in total?

void Func1(int N)
{
	int count = 0;
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			++count;
		}
	}
	for (int j = 0; j < N; ++j)
	{
		++count;
	}
	int M = 10;
	while (M--)
	{
		++count;
	}
	printf("%d\n", count);
}

 We can calculate the execution times of ++count in Func1 separately. There are three loops in Func1, and the first loop is a nested for loop.

The number of times ++count is executed in the first loop is N*N times

The number of times ++count is executed in the second loop is N times

The number of executions of ++count in the third loop is M  times, where M=10

This leads to the functional formula of time complexity: F(N)=N^2+2*N+10

Through this functional formula of time complexity, we found that when N is larger, the impact of the latter two items on the result is smaller:

 In practice, when we calculate the time complexity, we do not necessarily need to calculate the exact number of executions, but only the approximate number of executions, so here we use the asymptotic representation of big O
 

Asymptotic notation for big O

Big O notation (Big O notation): is a mathematical notation used to describe the asymptotic behavior .
Derivation of the Big O method:

1. Replace all additive constants in run time with the constant 1 . 2. In the modified running times function, only the highest order term is kept . 3. If the highest-order item exists and is not 1, remove the constant multiplied by this item , and the result is the big-O order.

Example 1: Calculate the time complexity of Func2?

void Func2(int N)
{
	int count = 0;
	for (int k = 0; k <= 2 * N; k++)
	{
		++count;
	}

	int M = 10;

	while (M--)
	{
		++count;
	}

	printf("%d\n", count);
}

 First, according to the previous example, we can easily get the exact time complexity of Func2: F(N)=2N+10

Then according to the asymptotic representation of big O , remove the constant 2 multiplied by this item and the addition constant 10, and finally get its space complexity: O(N)

Example 2: Calculate the time complexity of Func3?

void func3(int N, int M)
{
	int count = 0;
	for (int k = 0; k < M; ++k)
	{
		++count;
	}
	
	for (int k = 0; k < N; ++k)
	{
		++count;
	}

	printf("%d\n", count);
}

This question does not explain the size relationship between M and N, so the time complexity is: O(M+N)

but:

If M is much larger than N , we can think that the time complexity is O(M) ;

If M is much larger than N , we can think that the time complexity is O(N) ;

If the size of M and N are similar , we can think that the time complexity is O(N) or O(M) ;

Special reminder: In general, N is used for unknowns in time complexity calculations, but it can also be M, K, etc.

Example 3: Calculate the time complexity of Func2?

void Func4(int N)
{
	int count = 0;
	for (int k = 0; k < 100; ++k)
	{
		++count;
	}

	printf("%d\n", count);
}

 This function does not give us an unknown number, but directly gives us a constant of 100. Some friends may think that its time complexity is O(100), but this is not the case. The first article of the asymptotic notation of big O reads: 1. Replace all the addition constants in the running time with the constant 1,   so the time complexity of the func4 function is O(1) !

At the same time, we also need to know that the time complexity O(1) does not mean that only one operation can be performed, but a constant number of operations .

Example 4: Calculate the time complexity of strchr?

const char* strchr(const char* str, int character);

 First of all, we need to understand the general content of strchr:

According to the worst running result, the time complexity of strchr is O(N) (N is the length of *str)

Example 5: Calculate the time complexity of Bubblesort?

void Bubb1eSort(int* a,int n)
{
	assert(a);
	for (size_t end = n; end > 0; --end)
	{
		int exchange = 0;
		for (size_t i = 1; i < end; ++i)
		{
			if (a[i - 1] > a[i])  
			{
				Swap(&a[i - 1],& a[i]);
				exchange = 1;
			}
		}
		if (exchange == 0)
			break;
	}
}

 Let's first analyze the process of bubble sorting:

When end=n: the second layer of for loop executes N-1 times

When end=n-1: the second layer of for loop executes N-2 times

When end=n-2: the second layer of for loop executes N-3 times

When end=n-3: the second layer of for loop executes N-4 times

 ——

When end=2: The second layer of for loop is executed once

The total number of executions is 1+2+3+4+..+N=N*(N-1)/2

 So the time complexity of Bubblesort is O(N^2)

This example indirectly shows that the calculation of time complexity can not only look at a few layers of loops, but also depends on its thinking

Example 6: Calculate the time complexity of BinarySearch?

int BinarySearch(int* a,int n,int x)
{
	assert(a);
	int begin = 0;
	int end = n;
	while (begin < end)
	{
		int mid = begin + ((end - begin) >> 1);
		if (a[mid] < x)
			begin = mid + 1;
		else if (a[mid] > x)
			end = mid;
		else
			return mid;
	}
	return-1;
}

Computing the time complexity of binary search is also looking at its worst case:

The range to be searched at the beginning is N, and the range is doubled each time it is searched, that is, N/2/2/2/....(N>=0)

So the time complexity of binary search is O(log 2 N)

Example 7: What is the time complexity of calculating factorial recursive Fac?

long long Fib(size_t N)
{
	if (N < 3)
		return 1;
	return Fib(N - 1) + Fib(N - 2);
}

 It's a bit cumbersome to explain, so it's better to look at the picture directly:

The concept of spatial complexity

Space complexity is also a mathematical function expression, which is a measure of the temporary storage space occupied  by an algorithm during operation .
Space complexity is not how many bytes the program occupies, because this is not very meaningful, so space complexity is calculated by the number of variables.
The space complexity calculation rules are basically similar to the practical complexity, and the big O asymptotic notation is also used.
Note: The stack space (storage parameters, local variables, some register information, etc.) required by the function at runtime has been determined during compilation, so the space complexity is mainly determined by the extra space explicitly requested by the function at runtime .

Computational Methods for Space Complexity

Example 1: Calculate the space complexity of Bubblesort?

​void Bubb1eSort(int* a,int n)
{
	assert(a);
	for (size_t end = n; end > 0; --end)
	{
		int exchange = 0;
		for (size_t i = 1; i < end; ++i)
		{
			if (a[i - 1] > a[i])  
			{
				Swap(&a[i - 1],& a[i]);
				exchange = 1;
			}
		}
		if (exchange == 0)
			break;
	}
}

Only two variables are defined in the function - end and i

Although end and i will be destroyed every time the loop passes through, when the loop starts again, define  end  and  again and they still use the original space, so the extra space used by the function is 2 .

So the space complexity of this question is: O(1)

Example 2: Calculate the space complexity of Fibonacci?

Returns the first n terms of the Fibonacci sequence

1ong 1ong * Fibonacci(size_t n)
{
	if (n == 0)
		return NULL;

	1ong 1ong * fibArray = (1ong 1ong*)ma11oc((n + 1) * sizeof(1ong 1ong));
	fibArray[0] = 0;
	fibArray[1] = 1;
	for (inti = 2; i <= n; ++i)
	{
		fibArray[i] = fibArray[i - 1] + fibArray[i - 2];
	}

	return fibArray;
}

 Obviously, the space complexity is O(N), because an array of n+1 is opened

 By the way, calculate its time complexity: There is only one layer of for loop in the O(N)  function

Example 3: Calculate the space complexity of factorial recursive Fac?

1ong 1ong Fac(size_t N)
{
	if (N == 1)
		return 1;

	return Fac(N - 1) * N;
}

Each recursion must create a stack frame, and each stack frame creates a constant number of variables, and recurses n times to create n stack frames, so the space complexity is O(N)

The space complexity of recursive functions is related to the depth of recursion

Applications of Time and Space Complexity

disappearing numbers

Link to the original title: Likou

 Ideas:

 Method 1 : First sort the elements in the array, you need to use qsort to quickly sort, and the time complexity is O(n*log2N)

 Method 2 : First find the sum of the first n items and sum=(1+n)*n/2 , and then the required number x=sum-(a[0]+a[1]+a[2]+...+ a[n-1]) , the time complexity is O(N), and the space complexity is O(1)

Method 3 : Create an array of length n, write the value at the position where the median value of the original array is, and then traverse the array to find the item that has no value. The time complexity is O(N), and the space is complex. degree is O(N)

Method 4 : Give a value x=0, let x be XORed with 0~n first, then let x be XORed with each value in the array, and finally x is the required number, and the time complexity is O(N)

Use method four to solve the problem:

int missingNumber(int* nums, int numsSize)
{
    int x=0;
    //跟[0,n]异或
    for(int i=1;i<=numsSize;i++)
    {
        x^=i;
    }
    //在跟数组中值异或
    for(int i=0;i<numsSize;i++)
    {
        x^=nums[i];
    }
    return x;
}


 

rotation array

Link to the original title: Likou

 Method 1 : violent solution, rotate k times time complexity is O(N*K), space complexity is O(1)

Method 2 : Open up additional space to exchange space for time. The time complexity is O(N), and the space complexity is O(N)

 

 Method 3 : first reverse the first nk, then reverse the last k, and finally reverse the whole, the time complexity is O(N), and the space complexity is O(1)  

Use method three to solve the problem:

void reverse(int*nums,int left,int right)
{
    while(left<right)
    {
        int tem=nums[left];
        nums[left]=nums[right];
        nums[right]=tem;
        ++left;
        --right;
    }
} 

void rotate(int*nums,int numsSize,int k)
{
    if(k>=numsSize) k%=numsSize;
    //前n-k个数逆置
    reverse(nums,0,numsSize-k-1);
    //后k个逆置
    reverse(nums,numsSize-k,numsSize-1);
    //整体逆置
    reverse(nums,0,numsSize-1);
}

The full text is over~~

Guess you like

Origin blog.csdn.net/m0_73648729/article/details/129462466