2

After taking a short or long annual leave, the problem-solving series continues to work~

image.png
This topic aims to share some interesting or valuable topics found in the process of brushing Leecode.

topic related

  • Original title address: https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/ ]
  • Topic description:

    Input a positive integer target, output all consecutive positive integer sequences (at least two numbers) whose sum is target. The numbers in the sequence are arranged from small to large, and the different sequences are arranged from small to large according to the first number.

    • Example 1:
      enter : target=9
      outputs : [[2,3,4],[4,5]]
    • Example 2:
      input : target=15
      outputs : [[1,2,3,4,5],[4,5,6],[7,8]]
      limit : 1 <= target <= 10^5

Analysis of ideas

Brute force

The meaning of the title is relatively clear, and it is necessary to find a sequence of consecutive positive integers whose sum is a specific value.

First of all, this question is very direct and also think of one -- brute force cracking:

image.png

specific ideas :

  • First find out if there is a sequence that meets the requirements, with 1, so initialize a sequence as [ 1 ]
  • Add consecutive positive integers to the sequence in turn, so that the sequence becomes [1, 2, 3..i. target] , and each time an integer is added, compares the sum of all integers in the current sequence, and the relationship between the target value target :

    • If sum < target , continue to add the next number to the sequence;
    • If sum = target has been satisfied, then stores the current sequence , and indicates that can stop by searching for a sequence starting with 1;
    • If you go directly to sum > target , it means that can stop searching for sequences starting with 1 (there is no sequence that starts with 1 and meets the requirements);
  • Repeat the above steps to find sequences starting with 2, 3, ... target and satisfying the meaning of the question;

划重点.png

In the worst case of the above idea, the outer loop (the outer loop is to traverse the sequence starting with 1..n) is n times, and the inner loop is n times (the inner loop is to find the current beginning fixed, sequences with different endings), then the total complexity is O(n^2) , because 1 <= target <= 10^5 , so O(n^2) obviously timed out;

The red area represents the sequence. Its left and right boundaries have a characteristic. Both only move to the right, and the entire traversal process is actually like a sliding window movement process, which is how the algorithm gets its name.

sliding window

As can be seen from the above process, the problem of brute force cracking is that the time complexity of is too high , and the reason is high because has some skipped processes in the traversal process. In order to facilitate understanding, we bring in a problem Example 1 in the case of target = 9 to demonstrate. According to the brute force cracking idea:

  • The first sequence is [1] , the sum of the sequence is sum = 1 , 1 < 9 to continue the cycle;
  • The sequence is [1, 2] , the sum of the sequence is sum = 3 , 3 < 9 to continue the loop;
  • The sequence is [1, 2,3] , the sum of the sequence is sum = 6 , 6 < 9 to continue the loop;
  • The sequence is [1, 2, 3 ,4] , the sum of the sequences is sum = 12 , 12 > 9 , then Stop!;
    At this point, it means that there is no sequence that with 1 to meet the requirements, then according to the previous idea, the next step is to find the sequence that starts with 2 and meets the meaning of the question, then now the problem comes:

image.png

we really need to start with [2] ? When looking for the sequence starting with 1, we have found that the sum of [1,2,3] is less than the target, then the sum of the sequence [2,3] must also be less than 9, so why do we have to follow the steps, first go [2] , then go to [2,3] , then go to [2,3,4] ?

This is the key to breakthrough!

image.png

So we found that after finding the sequence starting with i, when jumping to find the sequence starting with i+1, we can skip some intermediate traversal times, we can do this:

  • The sequence is [1, 2, 3 ,4] , and the sum of the sequence is sum = 12, 12 < 9 . At this time, we need to stop looking for the sequence that starts with 1, then we directly remove the value on the left of the sequence and start looking for the sequence starting with 2 from [2,3,4] ;
  • According to the rules, the sum of [2, 3 ,4] is exactly 9 . At this time, the current sequence result is saved, and stops searching for the sequence that starts with 2 and meets the requirements. Next, we are to find the sequence starting with 3. Left value, starts from [3, 4] ;

Repeating the above process, you will find that during the traversal process, our sequence is as shown in the following figure (too lazy to make animations, it is easier to understand if you look at them separately):
image.png
image.png
image.png
image.png

The red area of represents the sequence. Its left border and right border have a characteristic. Both only move to the right, and the entire traversal process is actually like the moving process of a sliding window. This is named.

Of course, to use the above algorithm, we have to answer a question: Compared with brute force cracking, the sliding window does reduce the number of loops, but can the sliding window find all the solutions? (that is, what does the above jump process lead to omission?)

This is provable, because according to the previous traversal idea:

  • When looking for a sequence starting with 1, as long as the sum of the sequence is less than target , the right border of the window has been extended to the right until [1,2,3] is found, and the [1,2,3,4] of the sequence values is still less than target ; The first time is greater than target , indicating that with 1 to find the end of ;
  • Then the sequence starting with 2 is [2,3] < [1,2,3] < target , which means that only needs to start looking for from [2,3,4]. By analogy, it shows that the algorithm of sliding window will not be omitted.

full code

Here we only need to sort out the previous ideas, and the pseudo code will come out:

  • Initialize, set the left and right boundaries of the sequence window, respectively 1,2 , and then start the loop;
  • Loop, when the sum in the sequence is less than target, the right boundary is shifted to the right;
  • If the loop process finds that the sum of the sequence value is equal to the target t, the current sequence is stored and the left boundary is shifted to the right;
  • In the loop process, if the sum of the sequence value of is found to be greater than the target, will move the left border to the right;
  • When the left boundary catches up with the right boundary, the loop ends (can think about why?)

Then the actual code is as follows:

var findContinuousSequence = function(target) {
  const res = [];
  const sum = [0, 1];
  let l = 1; // 左边界
  let r = 2; // 右边界
  let s = 3; // 当前序列之和sum
  while(l < r){
      if(s === target) {
          // 满足题意的序列添加到结果
          res.push(getList(l, r));
      }

      if(s > target) {
          s = s - l;
          l++;
      } else {
          r++;
          s += r; 
      }
  }
  return res;
};

function getList (l, r) {
  const res = [];
  for(let i = l; i<=r; i++) {
      res.push(i)
  }
  return res;
}

Then the content of the sliding window ends here~
image.png

also...

image.png
At the end of the article, I put a small advertisement and asked if there are any friends who want to come to the foreign company 955:

  • Facing the sea to get off work, you can get off work on time without clocking in or checking in, so you can keep both work and life together;
  • Long vacations (annual annual leave + paid sick leave + corporate annual leave = 20 days to start !);
  • And many positions can be long ! No longer troubled with the problem of high first-line housing prices difficult to land;
  • Can be pushed internally, base Hangzhou and Xiamen~

安歌
7k 声望5.5k 粉丝

目前就职于Ringcentral厦门,随缘答题, 佛系写文章,欢迎私信探讨.