"Sword Finger Offer"-41, and a continuous positive sequence of S

1. Knowledge points of this question

Double pointer

2. Title description

Xiao Ming likes math very much. One day when he was doing his math homework, he asked to calculate the sum of 9-16. He immediately wrote that the correct answer was 100. But he was not satisfied with this, he was wondering how many consecutive positive sequences sum to 100 (including at least two numbers). It didn't take long for him to get another sequence of consecutive positive numbers with a sum of 100: 18,19,20,21,22. Now I leave the question to you, can you quickly find out all the continuous positive sequences whose sum is S? Good Luck!

Output all consecutive positive numbers whose sum is S. Follow the sequence from smallest to largest within the sequence, and follow the starting number in the sequence from smallest to largest between sequences.

输入:
9
返回值:
[[2,3,4],[4,5]]

3. Problem solving ideas

For this question, because it is a continuous search in a continuous sequence, you can use the idea of ​​a sliding window similar to the idea of ​​using a double pointer to locate the upper and lower boundaries of the sliding window, and use the two numbers low and high to point to the maximum and minimum values ​​in the current sequence respectively.

  1. Initialization, low=1, high=2
  2. If the sum of the values ​​in the window is less than the target value sum, it means that the window needs to be enlarged, high += 1
  3. If the sum of the values ​​in the window is greater than the target value sum, it means that the window needs to be reduced, low += 1
  4. Otherwise, it is equal to the target value, save the result, and reduce the window
  5. The left edge of the window can be terminated when it reaches half of sum, because the question requires at least 2 numbers

4. Code

public class Solution {
    
    
    ArrayList<ArrayList<Integer>> list = new ArrayList<>();

    public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {
    
    
        // 初始化
        int low = 1;
        int high = 2;
        // 窗口左边界走到 sum 的一半即可终止,因为题目要求至少包含 2 个数
        while (low <= sum / 2) {
    
    
            // 窗口中值的和
            int target = (low + high) * (high - low + 1) / 2;
            if (target < sum) {
    
    
                // 如果窗口中值的和小于目标值 sum,表示需要扩大窗口,high += 1
                high++;
            } else if (target > sum) {
    
    
                // 如果窗口中值的和大于目标值 sum,表示需要缩小窗口,low += 1
                low++;
            } else {
    
    
                // 否则,等于目标值,保存结果,缩小窗口
                ArrayList<Integer> temp = new ArrayList<>();
                for (int i = low; i <= high; i++) {
    
    
                    temp.add(i);
                }
                list.add(temp);
                low++;
            }
        }
        return list;
    }
}

Guess you like

Origin blog.csdn.net/bm1998/article/details/113047410