[C++ Code] Square of ordered array, subarray with minimum length, spiral matrix II--Code Thoughts

Topic: Square of ordered array

  • Given an array of integers sorted in non-decreasing ordernums , return a new array consisting of the square of each number , also sorted in non-decreasing order .
answer
  • The array is actually ordered, but the square of a negative number may become the largest number. Then the maximum square value of the array is at both ends of the array, either the leftmost or rightmost value, and it cannot be in the middle . You can use two pointers to point to positions 0 and n−1 respectively, compare the numbers corresponding to the two pointers each time, choose the larger one, put the answer in reverse order , and move the pointer. Time complexity: O(n), where n is the length of the array nums. Space complexity: O(1). In addition to the array to store the answers, we only need to maintain constant space.

  • If A[i] * A[i] < A[j] * A[j]then result[k--] = A[j] * A[j];. If A[i] * A[i] >= A[j] * A[j]then result[k--] = A[i] * A[i];.

  • class Solution {
          
          
    public:
        vector<int> sortedSquares(vector<int>& nums) {
          
          
            int left=0,right=nums.size()-1;
            int ptr_index = nums.size()-1;
            vector<int> res(ptr_index+1);
            while(left<=right){
          
          
                if(nums[left]*nums[left] < nums[right]*nums[right]){
          
          
                    res[ptr_index] = nums[right]*nums[right];
                    --right;
                }else{
          
          
                    res[ptr_index] = nums[left]*nums[left];
                    ++left;
                }
                --ptr_index;
            }
            return res;
        }
    };
    
  • The time complexity at this time is O(n), which is much improved compared to the solution of brute force sorting O(n + nlog n).

Topic: Subarray with minimum length

  • Given an narray of positive integers and a positive integer target. Find the contiguous subarray≥ target with the smallest length that satisfies its sum and return its length. If there is no matching subarray, return . [numsl, numsl+1, ..., numsr-1, numsr]0
answer
  • The violent solution to this problem is of course two for loops, and then continuously looking for subsequences that meet the conditions. The time complexity is obviously O ( n 2 ) O (n^2)O ( n2 ). Next, we will introduce another important method in array operations:sliding window. Code Random Record (programmercarl.com)

  • The so-called sliding window is to continuously adjust the starting position and ending position of the subsequence to obtain the result we want . In the brute force solution, a for loop is the starting position of the sliding window, and a for loop is the ending position of the sliding window. Two for loops are used to complete a process of continuously searching the interval. So how does a sliding window use a for loop to complete this operation? If only one for loop is used to represent the starting position of the sliding window, how to traverse the remaining ending positions?

  • If only one for loop is used, then the index of this loop must represent the end position of the sliding window.

    • Insert image description here
  • To implement the sliding window in this question, the following three points are mainly determined:

    • What's inside the window? (The window is the smallest continuous subarray whose sum ≥ s)

    • How to move the starting position of the window? (If the value of the current window is greater than s, the window will move forward)

    • How to move the end position of the window? (The end position of the window is the pointer to traverse the array, which is the index in the for loop)

  • It can be found that the subtlety of the sliding window is to continuously adjust the starting position of the subsequence according to the current subsequence and size. Thus O ( n 2 ) O(n^2)O ( n2 )The brute force solution is reduced to O(n).

  • Don't think that putting a while in for means it is O ( n 2 ) O(n^2)O ( n2 )Ah, it mainly depends on the number of times each element is operated.Each element comes in and operates once after the sliding window and goes out once. Each element is operated twice, so the time complexity is 2 × n, that is O(n).

  • class Solution {
          
          
    public:
        int minSubArrayLen(int target, vector<int>& nums) {
          
          
            int len_nums = nums.size();
            int sum = 0;
            int start_index = 0,sub_len=len_nums+3;
            for(int i = 0;i<len_nums;i++){
          
          
                sum += nums[i];
                while(sum>=target){
          
          
                    sub_len = min(sub_len,i-start_index+1);
                    sum -= nums[start_index];
                    start_index++;
                }
            }
            return sub_len>len_nums?0:sub_len;
        }
    };
    

Title: Spiral Matrix II

  • Given a positive integer n, generate a square matrix containing all elements 1from n2to , and the elements are arranged in a spiral in clockwise n x norder matrix.
answer
  • This question does not involve any algorithm, it is a simulation process, but it does test the ability to control the code . Generation of simulation matrices. As required, the initial position is set to the upper left corner of the matrix, and the initial direction is set to the right. If the next position exceeds the matrix boundary or is a previously visited position, rotate clockwise and enter the next direction. Repeat this until n 2 n^2 is filled inn2 elements. To solve this problem, we must adhere to the principle of loop invariance. Simulate the process of drawing a matrix clockwise:

    • Fill the upper row from left to right

    • Fill right column from top to bottom

    • Fill down rows from right to left

    • Fill left column from bottom to top

  • Draw this from outside to inside. Going around here, we have to draw every four sides. How to draw these four sides? We must insist on drawing each side.consistentThe principle of closing left and opening right, or opening left and closing right, so that this circle can be drawn according to unified rules.

  • class Solution {
          
          
    public:
        vector<vector<int>> generateMatrix(int n) {
          
          
            vector<vector<int>> res(n,vector<int>(n,0));
            int startx=0,starty=0;
            int cirle = n/2;
            int offset=1;
            int count=1;
            int i,j;
            while(cirle--){
          
          
                i=startx;
                j=starty;
                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++;
                }
                startx++;
                starty++;
                offset++;
            }
            if(n%2){
          
          
                res[startx][starty]=count++;
            }
            return res;
        }
    };
    

C++ STL four smart pointers

  • The C++ Standard Template Library STL (Standard Template Library) provides us with a total of four smart pointers: auto_ptr, unique_ptr, shared_ptr and weak_ptr . Among them, auto_ptr was proposed in C++98. C++11 has abandoned it and proposed unique_ptr replaces auto_ptr. Although auto_ptr has been abandoned, it can still be used in actual projects, but it is recommended to use unique_ptr, which is safer. shared_ptr and weak_ptr are two smart pointers introduced by C++11 from the quasi-standard library Boost. In addition, the Boost library also proposes smart pointers such as boost::scoped_ptr, boost::scoped_array, and boost::intrusive_ptr. Although it has not yet been adopted by the C++ standard, four types of smart pointers from C++ STL can be used in development practice_c++ smart pointer_ Love Meow Big Carp's Blog-CSDN Blog .

  • The bottom layer of C++ smart pointers is implemented using reference counting . When a smart pointer applies for heap memory space, it will be equipped with an integer value (initial value is 1). Whenever a new object uses this heap memory, the integer value + 1; conversely, whenever a new object uses this heap memory, the integer value will be +1. When the object is released, the integer value is decremented by 1 . When the corresponding integer value of the heap space is 0, it means that no object uses it anymore, and the heap space will be released.

  • Every smart pointer is implemented as a class template, and shared_ptr is no exception. The definition of shared_ptr (where T represents the specific data type pointed to by the pointer) is located in <memory>the header file and is located in the std namespace. Therefore, when using this type of pointer, the program should contain the following 2 lines of code:

    • #include <memory>
      using namespace std;
      
unique_ptr
  • As a type of smart pointer, the unique_ptr pointer naturally also has the ability to "automatically release the heap memory space at the appropriate time". The biggest difference from the shared_ptr pointer is that the heap memory pointed to by the unique_ptr pointer cannot be shared with other unique_ptr . That is to say, each unique_ptr pointer has its own ownership of the heap memory space it points to.

  • This also means that the reference count of the heap memory space pointed by each unique_ptr pointer can only be 1. Once the unique_ptr pointer gives up ownership of the pointed heap memory space, the space will be immediately released and recycled.

  • Creates an empty unique_ptr pointer

    • std::unique_ptr<int> p1();
      std::unique_ptr<int> p2(nullptr);
      
  • Construct unique_ptr smart pointer and initialize certain data

    • std::unique_ptr<int> p3(new int);
      
  • Pointers based on the unique_ptr type do not share their own heap memory, so the unique_ptr template class in the C++11 standard does not provide a copy constructor, only a move constructor. For example:

    • std::unique_ptr<int> p4(new int);
      std::unique_ptr<int> p5(p4);//错误,堆内存不共享
      std::unique_ptr<int> p5(std::move(p4));//正确,调用移动构造 函 数 
      //值得一提的是,对于调用移动构造函数的 p4 和 p5 来说,
      //p5 将获取 p4 所指堆空间的所有权,而 p4 将变成空指针(nullptr)。
      
  • By default, the unique_ptr pointer uses the std::default_delete method to release heap memory. Release rules can also be customized. Unlike shared_ptr pointers, unique_ptr custom release rules can only be in the form of function objects.

shared_ptr
  • It is worth mentioning that, unlike unique_ptr and weak_ptr, multiple shared_ptr smart pointers can share the same heap memory. Moreover, since this type of smart pointer is implemented using a reference counting mechanism, even if one shared_ptr pointer gives up the "right to use" the heap memory (the reference count is decremented by 1), it will not affect other shared_ptr pointers pointing to the same heap of memory. (Heap memory will be automatically released only when the reference count is 0).

  • Construct a null smart pointer of type shared_ptr

    • std::shared_ptr<int> p1; //不传入任何实
      std::shared_ptr<int> p2(nullptr); //传入空指针 nullptr
      
  • Construct shared_ptr smart pointer and initialize certain data

    • std::shared_ptr<int> p3(new int(10));
      std::shared_ptr<int> p3 = std::make_shared<int>(10);
      //调用拷贝构造函数
      std::shared_ptr<int> p4(p3);//或者 std::shared_ptr<int> p4 = p3;
       //调用移动构造函数
      std::shared_ptr<int> p5(std::move(p4)); //或者 
       std::shared_ptr<int> p5 = std::move(p4);
      
  • As shown above, p3 and p4 are both smart pointers of shared_ptr type, so p3 can be used to initialize p4. Since p3 is an lvalue, the copy constructor will be called. It should be noted that if p3 is a null smart pointer, then p4 is also a null smart pointer, and its initial reference count is 0; otherwise, it means that p4 and p3 point to the same piece of heap memory, and the reference count of the heap space will be increased. 1. For std::move(p4), this function will force p4 to be converted into the corresponding rvalue, so the move constructor is called to initialize p5. In addition, unlike calling the copy constructor, initializing p5 with std::move(p4) will make p5 own the heap memory of p4, and p4 becomes a null smart pointer.

  • Note : An ordinary pointer cannot assign values ​​​​to multiple shared_ptr objects at the same time, otherwise it will cause an exception in the program. For example:

    • int* ptr = new int;
      std::shared_ptr<int> p1(ptr);
      std::shared_ptr<int> p2(ptr);//错误
      
  • When initializing the shared_ptr smart pointer, you can customize the release rules of the heap memory. When the reference count of the heap memory is 0, the customized release rules will be called first.

    • //指定 default_delete 作为释放规则
      std::shared_ptr<int> p6(new int[10], std::default_delete<int[]>());
      //自定义释放规则
      void deleteInt(int*p) {
              
              
       delete []p;
      }
      //初始化智能指针,并自定义释放规则
      std::shared_ptr<int> p7(new int[10], deleteInt);
      

weak_ptr

  • Although the C++11 standard positions weak_ptr as a type of smart pointer, this type of pointer is usually not used alone (has no practical use) and can only be used in conjunction with shared_ptr type pointers . Even, we can regard the weak_ptr type pointer as an auxiliary tool for the shared_ptr pointer. With the help of the weak_ptr type pointer, we can obtain some status information of the shared_ptr pointer, such as how many pointers point to the same shared_ptr pointer and whether the heap memory pointed to by the shared_ptr pointer is Has been released and so on .

  • It should be noted that when the pointer of the weak_ptr type pointer is the same as a shared_ptr pointer, the weak_ptr pointer will not increase the reference count of the pointed heap memory by 1; similarly, when the weak_ptr pointer is released, the reference count of the previously pointed heap memory will be The reference count will not be decremented by 1. In other words, the weak_ptr type pointer does not affect the reference count of the pointed heap memory space .

std::unique_ptr : The owner or manager of the memory must be unique . If entering a different module or caller, an ownership transfer is performed.

std::shared_ptr : Memory is used jointly by multiple pointer variables , which jointly share ownership of the memory. But circular copying must be eliminated!

std::weak_ptr : The use of memory is only access, and does not involve the management of its life cycle.
1. In other words, the weak_ptr type pointer does not affect the reference count of the pointed heap memory space .

Guess you like

Origin blog.csdn.net/weixin_43424450/article/details/132483963