Day 2 | 209. Minimum length subarray

Reference:
Code Caprice [Sub-array with the smallest length]

zero, description

Given an array of n positive integers and a positive array target.

Example:
Input: target = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation: The subarray [4,3] is the subarray with the smallest length under this condition.

Input: target = 4, nums = [1,4,4]
Output: 1

Input: target = 11, nums = [1,1,1,1,1,1,1,1]
Output: 0

1. Solution: violent solution

Two for loops, and then keep looking for qualified subsequences,
time complexity: O ( n 2 ) O(n^2)O ( n2)

code:

class Solution {
    
    
public:
    int minSubArrayLen(int s, vector<int>& nums) {
    
    
        int result = INT32_MAX; // 最终的结果
        int sum = 0;            // 子序列的数值之和
        int subLength = 0;      // 子序列的长度
        for (int i = 0; i < nums.size(); i++) {
    
     
        // 设置子序列起点为i
            sum = 0;
            for (int j = i; j < nums.size(); j++) {
    
     
            // 设置子序列终止位置为j
                sum += nums[j];
                if (sum >= s) {
    
     
                // 一旦发现子序列和超过了s,更新result
                    subLength = j - i + 1; 
                    // 取子序列的长度
                    result = result < subLength ? result : subLength;
                    break; 
                    // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
                }
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == INT32_MAX ? 0 : result;
    }
};

2. Solution: sliding window

Sliding window: The essence is still that the double pointer
is still constantly adjusting the starting position and ending position of the subsequence, so as to get the result we want; in the violent solution, it is the starting position of a for loop sliding window, and a for loop As the end position of the sliding window, two for loops are used to complete a process of continuously searching the interval.

If a for loop is used, should it indicate the starting position of the sliding window, or the ending position?

  • Only one for loop is used to represent the starting position of the sliding window , so how to traverse the remaining ending positions?
  • So only one for loop is used, then the index of this loop must indicate the end position of the sliding window
    End position: the window is the continuous sub-array with the smallest length satisfying its sum ≥ target

The essential:

  • First find a continuous sub-array from the beginning whose sum is greater than the target, the function is to fix the right pointer
  • At this time, start to move the left pointer, and the left pointer moves. When the sum of the continuous sub-arrays is less than the target, the left pointer is fixed
  • Then move the right pointer so that the continuous sub-array is larger than the target, and fix the right pointer
  • Cycle through the above steps

the complexity:

  • Time complexity: O(n^2) brute force solution is reduced to O(n).
    Don’t think that putting a while in for is O(n^2). It
    mainly depends on the number of times each element is operated. After the sliding window, the operation comes in once, and the operation goes out once. Each element is operated twice, so the time complexity is 2 × n, which is O(n).
  • Space complexity: O(1)

insert image description here

code:

class Solution {
    
    
public:
    int minSubArrayLen(int target, vector<int>& nums) {
    
    
        int result = INT32_MAX;	//给一个很大的值
        int sum = 0; 			// 滑动窗口数值之和
        int i = 0;   			// 滑动窗口起始位置
        int subLength = 0; 		// 滑动窗口的长度
        
        // j 指的是终止位置
        for (int j = 0; j < nums.size(); j++) {
    
    
            sum += nums[j];
        	// 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
		
        	// 1.先找到前j项和大于等于target的j
            while ( sum >= target ) {
    
     
                subLength = (j - i + 1); 					      // 取子序列的长度
                result = result < subLength ? result : subLength; //result表示当前的最短长度
                sum -= nums[i++]; 						// 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == INT32_MAX ? 0 : result;
    }
};

3. Summary

Double pointers can be thought of, but they always fall into the circle of violent solutions.
The key is to think that what is fixed first is not the starting point (or called the left pointer), but the end point (the right pointer).
First try to step up the steps with your right foot. After fixing the right foot, move the left foot.
After moving the left foot, if the conditions are not met, move the right foot again.

Guess you like

Origin blog.csdn.net/weifengomg/article/details/128237778