当前位置:网站首页>Time complexity and space complexity

Time complexity and space complexity

2022-07-05 05:27:00 solemntee


p.s. It's the annual school season again ~

Time complexity

When the amount of data becomes larger , The program runs longer , We use complexity to describe the relationship between program running time and data volume
Program 1

int cnt,a[100005];
for(int i=1;i<=n;i++)cnt+=a[i];

This program puts a [ 1 ] a[1] a[1] To a [ n ] a[n] a[n] Add up , So the running time of the program is the same as n n n It's linear , Remember to do O ( n ) O(n) O(n)

Program 2

int cnt,a[100005][100005];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)cnt+=a[i][j];

This program puts a [ 1 ] [ 1 ] a[1][1] a[1][1] To a [ n ] [ n ] a[n][n] a[n][n] Add up , So the running time of the program is the same as n 2 n^2 n2 It's linear , Write it down as O ( n 2 ) O(n^2) O(n2)

Some common time complexity

Bubble sort 、 Selection sort O ( n 2 ) O(n^2) O(n2)
Merge sort 、 Quick sort O ( n l o g n ) O(nlogn) O(nlogn)
Ethmoidal method O ( n l o g n ) O(nlogn) O(nlogn)
Euler sieve method O ( n ) O(n) O(n)

The significance of computational complexity

The evaluation machine runs in about one second 5 ∗ 1 0 8 5*10^8 5108 Time , That is, the evaluation machine can run in one second 5 ∗ 1 0 8 5*10^8 5108 A simple operation ( + / − ∗ ) (+/-*) (+/) You need to control the complexity within 5 ∗ 1 0 8 5*10^8 5108 Within times of simple operation .

So we can also choose the algorithm by observing the data range , If it is 1 0 4 10^4 104 The complexity can be used as O ( n 2 ) O(n^2) O(n2) The algorithm of , 1 0 6 10^6 106 Sure O ( n l o g n ) O(nlogn) O(nlogn) too , 1 0 8 10^8 108 Sure O ( n ) O(n) O(n) too , exceed 1 0 8 10^8 108 Just O ( 1 ) O(1) O(1) too , That is, find out the law and judge directly .

Differential array and prefix array

example 1:
There is an array with length n Array of a [ i ] a[i] a[i], q q q Group inquiry , Every time I ask 1 1 1 To m m m in , a [ 1 ] + a [ 2 ] + a [ 3 ] + . . . a [ m ] a[1]+a[2]+a[3]+...a[m] a[1]+a[2]+a[3]+...a[m] And
n = 1 0 6 , q = 1 0 6 , 1 < = m < = n n=10^6,q=10^6, 1<=m<=n n=106,q=106,1<=m<=n

Idea one : Every time I go a [ 1 ] a[1] a[1] To a [ m ] a[m] a[m] Add up

for(int i=1;i<=m;i++)sum+=a[i];
printf("%d\n",sum);

Complexity is O ( n q ) O(nq) O(nq)( Because at most n n n All the numbers add up , At most q q q Time ), once n , q n,q n,q Is greater than 1 0 5 10^5 105, Our program timed out .
Because before i i i The number and , And the former i + 1 i+1 i+1 The sum of the numbers only differs a [ i + 1 ] a[i+1] a[i+1], There is no need to add it again every time , Therefore, the following methods are used to optimize it .

int a[100000],presum[100005];
for(int i=1;i<=n;i++)presum[i]=presum[i-1]+a[i];/// Add it first 
printf("%d",presum[m]);

In this way, the complexity of each inquiry becomes O ( n ) O(n) O(n)( Just started to get p r e s u m presum presum The array needs O ( n ) O(n) O(n) Time for ), In theory, it can be done through 1 0 8 10^8 108 The data of the , But when we submitted the program, we found that it was still T L E TLE TLE 了 , The reason is that synchronization flow is not related …

Just handled p r e s u m presum presum Arrays are prefixes and arrays , In this way, we can reduce the complexity of finding the sum of intervals very low , To calculate ∑ i = l r a [ i ] \sum^r_{i=l}a[i] i=lra[i] Just output p r e s u m [ r ] − p r e s u m [ l − 1 ] presum[r]-presum[l-1] presum[r]presum[l1] That's all right. , Save time .

example 2:
For a length of n ( n < 1 0 6 ) n(n<10^6) n(n<106) Sequence , We're going to do m m m operations . Every time I give it to you l , r l,r l,r, Let you a [ l ] , a [ l + 1 ] . . . , a [ r ] a[l],a[l+1]...,a[r] a[l],a[l+1]...,a[r] All plus one , Output m m m The sequence after the first operation .

If we put a [ i ] a[i] a[i] To a [ j ] a[j] a[j] all 1, Complexity is O ( n q ) O(nq) O(nq).
If title m = 1 0 6 m=10^6 m=106, Every time l = 1 , r = 1 0 6 l=1,r=10^6 l=1,r=106, It's over time .
At this time, we need to use an approximate optimization method : Difference array To optimize
Let's start with an array b [ N ] b[N] b[N]
When the operation makes a [ l ] , a [ l + 1 ] . . . , a [ r ] a[l],a[l+1]...,a[r] a[l],a[l+1]...,a[r] All add one hour , We make b [ l ] + + b[l]++ b[l]++, b [ r + 1 ] − − b[r+1]-- b[r+1]
At this point we observe b[N] Array and its prefix and :
b Array
0000000 1 The first l position 00000 ( − 1 ) The first r + 1 position 000 0 0 0 0 0 0 0 1_{ The first l position } 0 0 0 0 0 (-1)_{ The first r+1 position } 0 0 0 00000001 The first l position 00000(1) The first r+1 position 000
b Prefix and array preb
0000000 1 The first l position 111111 0 The first r + 1 position 00 0 0 0 0 0 0 0 1_{ The first l position } 11111 1 0_{ The first r+1 position } 0 0 00000001 The first l position 1111110 The first r+1 position 00
Find out b b b Prefix and array p r e b preb preb Is what we want a a a Array
This technique of using auxiliary arrays to optimize interval addition and subtraction is called differential array

That is to record a [ i ] − a [ i − 1 ] a[i]-a[i-1] a[i]a[i1] Value , The complexity of interval modification becomes O ( 1 ) O(1) O(1)( Only need to modify a [ i ] a[i] a[i] and a [ j + 1 ] a[j+1] a[j+1]), Just the complexity of querying a single element becomes O ( n ) O(n) O(n), Because you have to add up all the elements before it .

Reduce the number of repeated operations and reduce the time complexity :

Preprocessing

The prefix and mentioned above are the most common preprocessing methods . Preprocessing is a technique to improve program efficiency by processing some frequently used data in calculation in advance . The complexity of query results is O ( 1 ) O(1) O(1), Therefore, in the face of multiple groups of queries, we only need to pay the time complexity of preprocessing .
Here are some algorithms of prime numbers as examples :
In general , The complexity of judging whether a number is a prime number is O ( n 1 / 2 ) O(n^{1/2}) O(n1/2). Judge m m m The complexity of primes can be optimized to a very low , Because the prime numbers in a certain range are screened out before judgment , This can also be seen as a preprocessing optimization .

Some dry goods :《 Harmonic series optimization complexity 》

When learning the prime sieve method, we learned a kind of garbage sieve called the Egyptian sieve , His method is to enumerate the number and then enumerate the multiples of this number . The overall complexity is based on harmonic series O ( n l o g n ) O(nlogn) O(nlogn)

I recall that I did this optimized topic at the beginning of school Example : Maximum gcd, It is also calculated in the same way g c d gcd gcd It becomes enumeration g c d gcd gcd Multiple
Another use Harmonic series Optimize the complexity of the problem CF484B
In fact, in retrospect, the ideas are very similar , g c d gcd gcd Or the remainder can be enumerated a [ i ] a[i] a[i] To calculate the multiple of

Spatial complexity

Each program has an allowable memory size , If you exceed the allowed memory, you will receive M L E MLE MLE A hint of .
So how to calculate the allowed memory ?
We know one i n t int int Array needs to spend 32 32 32 Two binary bits to store , And a byte contains 8 8 8 Binary bits
So easy to calculate , 512 M B 512MB 512MB Memory can be stored 512 ∗ 1024 ∗ 1024 ∗ 8 / 32 ≈ 5 ∗ 1 0 7 512*1024*1024*8/32≈5*10^7 512102410248/325107 individual i n t int int, So it's commonly used 512 M B − > 6 ∗ 1 0 7 512MB->6*10^7 512MB>6107 You can know by proportional conversion a [ N ] a[N] a[N] Medium N N N How big can I drive ~

Scrolling array

When d p [ i ] [ j ] dp[i][j] dp[i][j] The transfer of is only related to d p [ i − 1 ] [ . . . ] dp[i-1][...] dp[i1][...] When it comes to space, we can change it from n 2 n^2 n2 Compression - 2 ∗ n 2*n 2n~

原网站

版权声明
本文为[solemntee]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140621453412.html