Question: Given an integer array A, find the maximum subscript distance ji if and only if A[i]<A[j] and i<j
Ideas given in the book:
Idea 1: Conventionally, the most intuitive solution we think of is
(1) i=0, j=end (end is the position of the last subscript), max=0
(2)如果A[i]<A[j],j-i>max,则max=j-i
(3)i++,j=end
(4) Repeat the second and third steps until i==j
The time complexity of this algorithm is 1+2+...+n-1 = (n-1)*(n-2)/2 = O(n^2)
Idea 2: Through observation, we can get such a rule that in the decreasing sequence, the decreasing sequence is the smallest (subscript i1). If there is an i2, such that i1<i2, A[i1]<A[i2], then if i2 <j and A[i2]<A[j], then the conditions i1<j and A[i1]<A[j] must be satisfied, then j-i1>j-i2 , first understand the above paragraph
Suppose: {5,3,4,0,1,4,1} this integer array
The core idea of the algorithm:
(1) Find the descending sequence (5,3,0 found here. Why can't it be 5,4,0? The subscript of the value 3 here is 1, and the subscript of the value 4 is 2. , there is a value greater than 4 subscript j after this descending sequence, then it must satisfy j-1>j-2, see the code in the book to find the descending sequence is very good)
(2) i=the subscript position with the smallest value, j=the last subscript position
(3) j--, if A[i]<A[j] and i<j are satisfied, then judge the size of max and ji, if max is less than ji, max=ji
If i>=j appears, then skip to the fifth step
(4) i--, if i is a member of the descending sequence, i>=0, then judge the size of A[i] and A[j],
If A[i]<A[j], judge the size of max and ji, if max is less than ji, max=ji
If A[i]>A[j], i-- has no meaning (because the value corresponding to the descending sequence smaller than the current i must be greater than A[j]), then skip the third step
If i<0, skip to the fifth step
(5) The max at this time is the maximum subscript distance
func maxIndexDistance (a [] int) int { if len(a) < 2 { return 0 } inDescSeq, min, n := make([]bool, 0), a[0], len(a) // step one for i := 0;i < n;i += 1 { inDescSeq = append(inDescSeq, false) if a[i] < min { // mark the descending sequence inDescSeq[i] = true min = a [i] } } // step two maxDist, i, j := 0, n - 1, n - 1 for i >= 0 { // third step if inDescSeq[i] == false { // The first time to find the elements of the descending sequence also belong, step 2 i-- continue } // fourth step for a[i] >= a[j] && j > i { j-- // move from back to front until a matching element is found, } if (j - i) > maxDist { maxDist = j - i } i-- } // fifth step return maxDist }
A total of three linear scans have been performed above, and the time complexity of each scan is O(n), so the time complexity of the entire algorithm is O(n)