Two methods to solve LeetCode and continuous positive sequence of s

Title descriptionInsert picture description here

Method 1: Mathematical Method

The first time the method I thought of was not only passed, but also very efficient. Let’s take a look at the submitted results of the mathematical method.
Insert picture description here
In fact, the idea is also very simple: the sequence obtained by analyzing the problem is an arithmetic sequence, then we only need to know the starting point of each sequence. With the initial value and the length of the sequence, we can construct the entire sequence, then use a temporary vector to save the sequence, and finally add the temporary vector to the two-dimensional array (vector<vector> res).

  • First determine the size of the sequence, the size of the sequence is [2,sqrt(2*target)]
    • Because the sequence is constructed when the starting value of the sequence is 1, the length of the sequence is the longest. From the arithmetic sequence formula, the length is sqrt(2*target).
  • With the length n of the sequence, and the sum target of the arithmetic sequence, now the starting value of the sequence can be obtained, and then the sequence can be constructed. The starting value s, the number sequence length n, and the target value target can only be constructed when the following relations are satisfied
    (2 ∗ s + n − 1) ∗ n / 2 = target \quad\quad\quad\quad\quad\quad(2 *s+n-1)*n/2 = target(2s+n1)n/2=target
    • At this time, in order to obtain the starting value of the sequence perfectly, we need
      2 ∗ target / n 2* target/n2target/n ( 2 ∗ t a r g e t / n + 1 − n ) / 2 (2*target/n+1-n)/2 (2target/n+1n ) / 2 is an integer at the same time. If this condition is met, an arithmetic sequence can be constructed

Attach the code:

vector<vector<int>> findContinuousSequence(int target) {
    
    
        vector<vector<int>> res;
        for(int n=(int)sqrt((double)target*2); n>=2; n--){
    
    
            if(2*target%n==0 && (2*target/n+1-n)%2==0){
    
    
                int s = (2*target/n+1-n)/2;//s表示数列起始值
                if(s < 1) continue;//起始值必须为正整数
                vector<int> temp;
                int len = n;
                while(len-- > 0){
    
    
                    temp.push_back(s++);
                }
                res.push_back(temp);
            }
        }
        return res;
    }

Method two: sliding window

It's easy to understand, I won't write the analysis process, refer to the solution: sliding window

int getSum(int left , int right){
    
    
    int res = 0;
    for(int i=left; i<=right; i++){
    
    
        res += i;
    }
    return res;
}
vector<vector<int>> findContinuousSequence(int target) {
    
    
    vector<vector<int>> res;
    int left = 1;
    int right = left + 1;
    while( left <= target/2 ){
    
    
        int sum = getSum(left, right);
        if(sum < target){
    
    
            right++;
            continue;
        }else if(sum > target){
    
    
            left++;
            continue;
        }else{
    
    
            vector<int> temp;
            for(int i=left; i<=right; i++){
    
    
                temp.push_back(i);
            }
            res.push_back(temp);
            left++;
            right++;
        }
    }
    return res;
}

No need to call the code of the getsum function every time

vector<vector<int>> findContinuousSequence(int target) {
    
    
        vector<vector<int>> res;
        int left = 1;
        int right = left + 1;
        int sum = getSum(left, right);
        while( left <= target/2 ){
    
    
            if(sum < target){
    
    
            	//先移动右侧窗口再修改sum值
                right++; 
                sum += right;//此时的区间和
            }else if(sum > target){
    
    
            	//先修改sum值,再移动左侧窗口
                sum -= left;
                left++;
            }else{
    
    
                vector<int> temp;
                for(int i=left; i<=right; i++){
    
    
                    temp.push_back(i);
                }
                res.push_back(temp);
                sum -= left;
                left++;//窗口左边界向右移动
                right++;//由于左边界移动了,显然右边界也要向右移动
                sum += right;
            }
        }
        return res;
    }

Guess you like

Origin blog.csdn.net/qq_42500831/article/details/105351721