Random Thoughts on Code 【Array】----->Square of ordered array, sub-array with minimum length, spiral matrix

977. Squaring an Ordered Array

题目LeetCode977. Squaring an Ordered Array
insert image description here

double pointer idea

After squaringThe elements on both sides are the largest and the elements in the middle are the smallest, so double pointers can be used.

  • Define left to point to the leftmost of the original array, and right to point to the rightmost of the original array
  • Compare the square of the left element with the square of the right element
  • The square of the left element is greater than the square of the right element, and the square of the left element is placed at the end of the result set, left++
  • The square of the right element is greater than the square of the left element, and the square of the right element is placed at the end of the result set, right–

insert image description here

the code

int* sortedSquares(int* nums, int numsSize, int* returnSize){
    
    
    int left = 0;
    int right = numsSize - 1;
    int* res = (int*)malloc(sizeof(int) * numsSize);
    *returnSize = 0;
    //数组平方
    for (int i = 0; i < numsSize; i++)
    nums[i] *= nums[i];
    while (left <= right)
    {
    
    
        if (nums[left] > nums[right]) 
        res[numsSize - 1 - (*returnSize)++] = nums[left++];
        else 
        res[numsSize - 1 - (*returnSize)++] = nums[right--];
    }
    return res;
}

insert image description here


209. Minimum Length Subarray

Title: LeetCode209. Minimum Length Subarray
insert image description here

Brute force solution

The violent solution to this question is of course two for loops, and thenContinuously look for qualified subsequences from the entire array head, the time complexity is obviously O(n^2).

int minSubArrayLen(int target, int* nums, int numsSize) {
    
    
    //暴力:
    int subSum = 0;//记录子串和
    int sublen = 0;//记录子串长度
    int res = INT_MAX;
    for (int i = 0; i < numsSize; i++)//循环变量记录子串头
    {
    
    
        subSum  = 0;//每一次子串头更新时字串和更新为0
        for (int j = i; j < numsSize; j++)//循环变量记录子串尾
        {
    
    
            subSum += nums[j];
            if (subSum >= target)//子串和超过目标值
            {
    
    
                sublen = j - i + 1;//统计子串长度
                res = res < sublen ? res : sublen;//记录最短字串长度
                break;//找到最短长度后直接break
            }
        }
    }
    //最短字串长度没有改变的话说明不存在子数组满足条件
    return res == INT_MAX ? 0 : res;
}

Sliding window ⭐️

The sliding window is to constantly condition the starting position and ending position of the substring , so as to obtain the result we want.
The brute force solution uses two layers of for loops, and the sliding window only uses one layer of for loops to complete what the two layers of loops do, so please think about what the loop variable in the one layer of for loops of the sliding window represents?The loop variable represents the end point of the window (substring)

  • If the loop variable represents the starting point, then we still need a loop variable to record the end point of the window, which requires another layer of for loop to find the end point of the window just like the violent solution
  • If the loop variable represents the end point of the window, then we only need one variable to record the starting point of the window. The key issue of the sliding window is how to change the starting point of the window

The question is how to represent the starting position of the sliding window?
Here is still an example in the title, s=7, the array is 2, 3, 1, 2, 4, 3, let’s take a look at the search process

insert image description here

Finally find 3 4 is the shortest substring

The three key points of this idea are

  1. What is a window?
  2. How to move the starting position of the window
  3. How to move the end position of the window?
  • A window is a substring whose sum of elements is greater than or equal to target
  • When the value of the window is greater than or equal to the target, the starting position of the window moves backward one space at a time
  • When the value of the window is less than target, the end position of the window moves back one space
 int minSubArrayLen(int target, int* nums, int numsSize) {
    
    
    //滑动窗口
    int subSum = 0;//记录子串和
    int res = INT_MAX;
    int sublen = 0;//记录子串长度
    int i = 0;//记录滑动窗口起始位置
    for (int j = 0; j < numsSize; j++)//循环变量是滑动窗口结束位置
    {
    
    
        subSum += nums[j];//统计子串和
        //子串和大于等于target
        while (subSum >= target)
        {
    
    
            sublen = j - i + 1;//字串长度
            subSum -= nums[i];//字串和减去窗口当前起始位置的值
              i++;//窗口起始位置向前滑动一个位置
            res = res < sublen ? res : sublen;//记录最小字串长度
        }
    }
    return res == INT_MAX ? 0 : res;//res没变表示不存在这样的子串
}

insert image description here


59. Spiral Matrix

题目LeetCode59. Spiral Matrix II
insert image description here

train of thought

It is easy to observe that the value of the matrix increases with each turn, so we can use a large loop outside to represent the number of turns of the loop. How to deal with each turn is the focus of our discussion

  • Each circle can be divided into 4 directions, left to right, up to down, right to left, down to up
  • Data processed in each direction cannot be duplicated

We can ensure that the data processed in each direction will not be repeated by processing data in one direction each time by closing left and opening right , and we must implement this principle of left closing and right opening in the process of processing , which is循环不变量
insert image description here

the code

int** generateMatrix(int n, int* returnSize, int** returnColumnSizes){
    
    
      //初始化返回的结果数组的大小
    *returnSize = n;
    *returnColumnSizes = (int*)malloc(sizeof(int) * n);
    //初始化返回结果数组ans
    int** martix = (int**)malloc(sizeof(int*) * n);
    int i;
    for(i = 0; i < n; i++) {
    
    
        martix[i] = (int*)malloc(sizeof(int) * n);
        (*returnColumnSizes)[i] = n;
    }
   int loop = n / 2;//循环loop圈
   int curNum = 1;//当前填充值
    for (int count = 0; count < loop; count++)
      {
    
    
          //初始化一圈的开始坐标
          int i = count, j = count;
        //保持左闭右开的原则从左向右赋值
        for ( ; j < n - 1 - count; j++) martix[i][j] = curNum++;
        //保持左闭右开的原则从上向下赋值
        for ( ; i < n - 1 - count; i++) martix[i][j] = curNum++;
        //保持左闭右开的元组从右向左赋值
        for ( ; j > count; j--)         martix[i][j] = curNum++;
        //保持左闭右开的原则从下向上赋值
        for ( ; i > count; i--)         martix[i][j] = curNum++;
      }
      //填充奇数圈正中间的值
      if (n % 2 == 1) martix[loop][loop] = curNum++;
      return martix;
}

insert image description here

Guess you like

Origin blog.csdn.net/m0_74278159/article/details/129987288