The second day of the code random recording algorithm training camp | 907 square of ordered array, 209 sub-array with the smallest length, 59 spiral matrix II

Links to Articles and Videos Learned Today

977 article link: link
977 video explanation link: link
209 article link: link
209 video explanation link: link
59 article link: link
59 video explanation link: link

977 Square of an array of numbers

See the title first thought

Because the title is to return the square of each number to form a new array for an integer array in non-decreasing order , it is also required to be sorted in non-decreasing order . Have the following ideas:

  1. First square the elements in the array
  2. The code for quick sorting of numerical values
    ​​is as follows:
class Solution {
    
    
public:
    vector<int> sortedSquares(vector<int>& nums) {
    
    
        for (int i = 0; i < nums.size(); i++) {
    
    
            nums[i] *= nums[i];
        }
        sort(nums.begin(), nums.end()); // 快速排序
        return nums;
    }

Thoughts after reading the code caprice

The violent sorting that I thought of was mentioned in the random thoughts of the code, and its time complexity is O(n + nlogn), but there is another method with lower time complexity-the double pointer method .

double pointer method

Because the array is ordered (it may contain negative numbers), the maximum value after the square of the array must be at both ends of the array, so the double pointer method can be considered, i points to the starting position, and j points to the ending position.

A new array result needs to be defined, the size of which is the same as nums, so that k points to the end position of the result array.

if nums[i] * nums[i] > nums[j] * nums[j]then result[k--] = nums[i] * nums[i]
if nums[i] * nums[i] <= nums[j] * nums[j]thenresult[k--] = nums[j] * nums[j]

Difficulties Encountered During Implementation

I vector<int> result(nums.size(), 0);don't quite understand this sentence
, query this as the method of initializing vector:


vector<int> result(nums.size(), 0); //初始化,第一个参数是数目,第二个参数是要初始化的值

the code

class Solution {
    
    
public:
    vector<int> sortedSquares(vector<int>& nums) {
    
    
        vector<int> result(nums.size(), 0);
        int k= nums.size()-1;
        for(int i = 0,j = nums.size()-1;i <= j;){
    
    
            if(nums[i] * nums[i] > nums[j] * nums[j]){
    
    
                result[k--] = nums[i] * nums[i];
                i++;
            }
            else{
    
    
                result[k--] = nums[j] * nums[j];
                j--;
            }
        }
        return result;
    }
};

209 The subarray with the smallest length

See the title first thought

Title description:
Given an narray containing positive integers and a positive integer target. Find the smallest continuous subarray
in the array that satisfies its sum [num sl s_l≥ targetsl, whether sl + 1 s_{l+1}sl+1, …, num s r − 1 s_{r-1} sr1, num s r s_r sr], and returns its length. If there is no subarray that meets the condition, return it 0.
Seeing the continuous sub-arrays required by the title to meet the requirements, I thought of the sliding window method.

Thoughts after reading the code caprice

The code random recording also recommends the sliding window method.

The meaning of the sliding window is to continuously adjust the starting position and ending position of the subsequence to get the result we want.

Only one for loop is used, and the index of this loop must indicate the end position of the sliding window.

So how to move the starting position of the active window?

If the value of the current window is greater than s, the window will move forward.

Difficulties Encountered During Implementation

The idea is correct, but it is a bit difficult to move the initial position of the window when actually operating the code.

This part of the code is as follows:

while (sum >= s) {
    
    
	subLength = (j - i + 1); // 取子序列的长度
 	result = result < subLength ? result : subLength;
	sum -= nums[i++]; //这里体现了滑动窗口的精髓之处,不断变更i(子序列的起始位置)

the code

class Solution {
    
    
public:
    int minSubArrayLen(int target, vector<int>& nums) {
    
    
        int result = INT32_MAX;
        int sum = 0;//滑动窗口数值之和
        int i = 0;//滑动窗口起始位置
        int subLength = 0;//滑动窗口长度
        for (int j = 0;j < nums.size();j++){
    
    
            sum += nums[j];
            while (sum >= target){
    
    
                subLength = (j - i + 1);
                result = result < subLength ? result : subLength;
                sum -= nums[i++];
            }
        }
        return result == INT32_MAX ? 0 : result;
    }
};

59 Spiral Matrix II

See the title first thought

Title description:
Give you a positive integer n, generate an integer containing 1 to n 2 n^2n2 All elements, and the elements are arranged in a clockwise order in a n x nsquarematrix.
After seeing this question, I thought that the key to solving this question is the handling of boundary conditions, and the principle of loop invariance must be adhered to.

Thoughts after reading the code caprice

What is emphasized in the random thoughts of code is to adhere to the principle of loop invariance .

Simulate the process of drawing a matrix clockwise:

  • Fill upper row left to right
  • Fill right column top to bottom
  • Fill descending row from right to left
  • Fill left column from bottom to top

Draw in a circle from the outside to the inside.

In such a loop, the key to processing is the boundary conditions . If you do not traverse according to fixed rules, it is easy to get lost in the loop.

Therefore, when drawing each side, we must adhere to the principle of left-closed and right-opened, or left-opened and right-closed, so that we can draw according to uniform rules and not get lost.

Difficulties Encountered During Implementation

There are many conditions to be judged in the while loop in the code . It is recommended to draw a dynamic graph to think about the change of conditions.
insert image description here

Image from Carl's Code Random Thoughts website

the code

class Solution {
    
    
public:
    vector<vector<int>> generateMatrix(int n) {
    
    
        vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
        int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
        int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
        int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
        int count = 1; // 用来给矩阵中每一个空格赋值
        int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
        int i,j;
        while (loop --) {
    
    
            i = startx;
            j = starty;

            // 下面开始的四个for就是模拟转了一圈
            // 模拟填充上行从左到右(左闭右开)
            for (j = starty; j < n - offset; j++) {
    
    
                res[startx][j] = count++;
            }
            // 模拟填充右列从上到下(左闭右开)
            for (i = startx; i < n - offset; i++) {
    
    
                res[i][j] = count++;
            }
            // 模拟填充下行从右到左(左闭右开)
            for (; j > starty; j--) {
    
    
                res[i][j] = count++;
            }
            // 模拟填充左列从下到上(左闭右开)
            for (; i > startx; i--) {
    
    
                res[i][j] = count++;
            }

            // 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
            startx++;
            starty++;

            // offset 控制每一圈里每一条边遍历的长度
            offset += 1;
        }

        // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
        if (n % 2) {
    
    
            res[mid][mid] = count;
        }
        return res;
    }
};

Harvest today

1. Master the sorting method of double pointer method, you can say byebye with violent sorting

2. When implementing a sliding window, consider the following three points:

  • What's inside the window?
  • How to move the window starting position?
  • How to move the window end position?

3. When encountering the spiral matrix problem, we must adhere to the principle of loop invariance to avoid getting lost in the loop

Today's study time is 3 hours

Guess you like

Origin blog.csdn.net/m0_46555669/article/details/126999364