Likou 896 monotone sequence (exclusive OR method)

Original title: 896. Monotone Sequence

If the array is monotonically increasing or monotonically decreasing, then it is monotonic.

If for all i <= j, A[i] <= A[j], then the array A is monotonically increasing. If for all i <= j, A[i]> = A[j], then the array A is monotonically decreasing.

It returns true when the given array A is a monotonic array, otherwise it returns false.

prompt:

  1. 1 <= A.length <= 50000
  2. -100000 <= A[i] <= 100000

Many people on the Internet use the multi-case discussion method, discussing greater than and less than cases, such as counting, etc. Here I use the exclusive-or method, that is, to find two subscripts i and j, if A[i]? Two of A[i-1] and A[j]? A[j-1]? (=, <or >) is an opposite sign (one is greater than one is less than), then it is not monotonous. i is the first subscript in A that is not equal to the previous element, that is, the subscript k before i, all satisfies A[k]==A[k-1], and A[i]>A[i- 1] Or A[i]<A[i-1], j is initialized to i+1, traversing to determine the size and sign of A[j] and A[j-1]. The specific situation is shown in the following table:

A[i]?A[i-1] A[j]?A[j-1] judgment
> < Not monotonous
> > Continue to judge j+1
> = Continue to judge j+1
< < Continue to judge j+1
< > Not monotonous
< = Continue to judge j+1

 

I have thought of two methods for judging the sign situation: the difference method and the judgment greater than (or less than) method.

1. The difference method is to multiply the results of A[i]-A[i-1] and A[j]-A[j-1]. If it is less than 0, it means that one of the two is less than 0 and the other is greater than 0, which means A[i]>A[i-1] and A[j]<A[j-1] or A[i]<A[i-1] and A[j]>A[j-1] If the number sequence is no longer monotonous, return false directly; if it is equal to 0, it means A[j]=A[j-1]. It cannot be judged whether it is monotonous. At this time, j needs to be shifted to the right. If it is greater than 0, it means A[i ]>A[i-1] and A[j]>A[j-1] or A[i]<A[i-1] and A[j]<A[j-1] are guaranteed A[0] to A[j] are monotonic, and move j to the right to continue the judgment.

class Solution {
public:
    bool isMonotonic(vector<int>& A) {
        int n=A.size();
        if(n==1){
            return true;
        }
        int i=1;
        while((i<n) && (A[i-1]==A[i])) i++;//找到第一个纯增/减
        for(int j=i+1;j<n;j++){
            if((A[j-1]-A[j])*(A[i-1]-A[i])<0){
                return false;
            }
        }
        return true;
    }
};

However, it takes time to calculate addition, subtraction, multiplication and division.

2. Judgment is greater than (or less than) method. Take the judgment of greater than as an example, use XOR:

判断A[i]>A[i-1] Judge A[j]>A[j-1] XOR result
true true false
true false true
false true true
false false false

The condition for judging non-monotonicity is that A[i]>A[i-1] and A[j]>A[j-1] are not equal, which are true, false or false, and true respectively, corresponding to their differences. Or true (first judge whether A[j] is equal to A[j-1] before judging, if it is equal, skip it)

Therefore, the code using XOR (^) is:

class Solution {
public:
    bool isMonotonic(vector<int>& A) {
        int n=A.size();
        if(n==1){
            return true;
        }
        int i=1;
        while((i<n) && (A[i-1]==A[i])) i++;//找到第一个纯增/减
        for(int j=i+1;j<n;j++){
            if (A[j-1]!=A[j]){
                if(((A[j-1]<A[j])^(A[i-1]<A[i]))==true){
                    return false;
                }                
            }

        }
        return true;
    }
};

Or directly judge A[i]>A[i-1]! = A[j]>A[j-1]

class Solution {
public:
    bool isMonotonic(vector<int>& A) {
        int n=A.size();
        if(n==1){
            return true;
        }
        int i=1;
        while((i<n) && (A[i-1]==A[i])) i++;//找到第一个纯增/减
        for(int j=i+1;j<n;j++){
            if (A[j-1]!=A[j]){
                if((A[j-1]<A[j])!=(A[i-1]<A[i])){
                    return false;
                }                
            }

        }
        return true;
    }
};

But the running time of the two seems to be the same.

All in all, this method can avoid the if (greater than or equal) else situation, and can be terminated early, but the fastest execution time currently is to use switch-case.

Guess you like

Origin blog.csdn.net/qq_36614557/article/details/114219139