代码随想录算法训练营第二天|977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II

977.有序数组的平方

文档讲解:https://programmercarl.com/0977.有序数组的平方.html#算法公开课
状态:没做出来

思路

想到了使用双向指针的方法,但是在插入元素的部分出现了一些定式思维,一直在想两个指针元素判断出来的最小值插入新数组中,下一个比较出来的最小值有可能比它小也可能比他大,就不知道该怎样插入了。

代码随想录思路

数组平方的最大值就在数组的两端,所以比较之后应该取最大值放在新数组的最后。
时间复杂度:O(n)

收获

用时1h。使用到了vector.insert(插入位置,插入元素个数,插入元素)/vector.emplace(插入位置,插入元素)函数,可以在数组指定位置插入n个/1个元素。

实现代码

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> num_result{};
        int left_point = 0;
        int right_point = nums. size() - 1;
        for (int i = 0; i <= right_point; ++i) {
            nums[i] = nums[i] * nums[i] ;
        }
        while (left_point <= right_point){
            if(nums[right_point] >= nums[left_point]){
                num_result.emplace (num_result.begin(), nums[right_point]);
                --right_point;
            }
            else if(nums[left_point] >= nums[right_point]){
                num_result.emplace (num_result.begin(), nums[left_point]);
                ++left_point;
            }
        }
        return num_result;
    }
};

209.长度最小的子数组

文档讲解:https://programmercarl.com/0209.长度最小的子数组.html
状态:做出来了,但是有几个测试用例超出了时间限制

思路

三层for循环嵌套,依次对起始位置、子数组长度、结束位置做循环以实现枚举找到子数组之和大于等于target的长度,但是时间复杂度太高了,对于比较大的元素就超出了时间限制。

代码随想录思路

使用滑动窗口的方法,只使用for循环移动结束位置的指针,然后依据两指针间元素和与target大小的比较结果,如果大于等于target的话左指针就向右移并不断判断大小比较结果直到加和小于target,在此过程中不断更新左右指针间的距离,最终取距离最小值即可。
时间复杂度:O(n),空间复杂度:O(1)

收获

用时1h.掌握了滑动窗口的思路,其核心就是一个指针一直动,另一个指针根据两指针间元素的性质来变动。
掌握了一个判断的语句i = i < j ? i : j,即i与j比较大小,如果i<j则i=i,否则i=j。

实现代码

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int nums_size = nums.size();
        int result_length = INT32_MAX;
        int result_sum = 0;
        int left_point=0;
        for(int right_point=0;right_point<nums_size;++right_point){
            result_sum += nums[right_point];
            while(result_sum>=target){
                int length_report = (right_point - left_point + 1);
                result_length = result_length < length_report ? result_length : length_report;
                result_sum -= nums[left_point];
                ++left_point;
            }
        }
        return result_length == INT32_MAX ? 0 : result_length;
    }
};

59.螺旋矩阵II

文档讲解:https://programmercarl.com/0059.螺旋矩阵II.html
状态:没做出来

思路

一脸懵,毫无思路。

代码随想录思路

其本质依然是双向指针,只不过是在二维数组的情况下,两个指针分别指向行和列。需要注意的有两点,一是处理四条边时对于边界的判断,二是进入不同圈数判断条件也有所不同。
时间复杂度:O(n^2),空间复杂度:O(1)

收获

用时2h,太难了。掌握了vector的二维数组初始化、各种处理,即vector<vector<int>> i(数组个数,vector<int>(元素个数,元素内容))

实现代码

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> num_result(n, vector<int>(n, 0));
        int point_loop = 0;                 // 循环圈数
        int nums_val = 1;                   // 填充内容
        int nums_mid = n / 2;               // 中心元素
        while(point_loop < nums_mid){
            for(int i = point_loop; i <n - point_loop - 1; ++i){
                num_result[point_loop][i] = nums_val++;
            }
            for(int j = point_loop; j < n - point_loop - 1; ++j){
                num_result[j][n - point_loop - 1] = nums_val++;
            }
            for(int i = n - point_loop - 1; i > point_loop; --i){
                num_result[n - point_loop - 1][i] = nums_val++;
            }
            for(int j = n - point_loop - 1; j > point_loop; --j){
                num_result[j] [point_loop] = nums_val++;
            }
            ++point_loop;
        }
        // 如果n为奇数,中间元素单独处理
        if (n%2==1){
            num_result[nums_mid][nums_mid] =n * n;
        }
        return num_result;
    }
};
posted @ 2024-01-25 22:01  冰小呱  阅读(9)  评论(0)    收藏  举报