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

Leetcode 977. 有序数组的平方
思路分析:本题直观的解法是先求出平方数组,然后对平方数组进行排序,如下面方法1。该方法可以实现功能,但未使用数组有序的特性,且快速排序是不稳定的排序,时间复杂度最好是o(nlogn),最坏是o(n2)。
时间复杂更低的方法是双指针法,因数组有序,平方后的最大值一定是右边值的平方或最左边值的平方,因此可用left指针指向最左侧元素,right指针指向最右侧元素。先把平方最大的值存放到result数组的末位,移动对应的指针,直到左右指针相遇,则result数组即为有序的结果数组。该方法的时间复杂度为o(n)

代码实现:
方法1:无序的平方数组+快速排序

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

    void quick_sort(vector<int>& arr, int left, int right )
    {
        if (left > right) {
            return;
        }
        int temp = arr[left];
        int i = left;
        int j = right;
        if(i<j)
        {
            while (i < j)
            {
                while(i<j && arr[j] >= temp)
                {
                    j--;
                }
                if(i<j)
                {
                    arr[i] = arr[j];
                    i++;
                }
                while(i<j && arr[i] < temp)
                {
                    i++;
                }
                if(i<j)
                {
                    arr[j] = arr[i];
                    j--;
                }
            }
            arr[i] = temp;
            quick_sort(arr, left,i-1);
            quick_sort(arr, j+1, right);
        }
    }
};

方法2:双指针

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> result(nums.size());
        int res_size = result.size()-1, left=0, right=nums.size()-1;
        while (left <= right) {
            if (nums[left]*nums[left] < nums[right]*nums[right]) {
                result[res_size] = nums[right]*nums[right];
                right--;
                res_size--;
            } else {
                result[res_size] = nums[left]*nums[left];
                left++;
                res_size--;
            }
        }
        return result;
    }
};

Leetcode 209.长度最小的子数组
思路分析:本题容易想到用滑动窗口的方法,只是需要统计滑动窗口内所有元素和是否大于等于target,另外需要统计出最小长度。注意如果滑动窗口内所有元素之和都小于target,则不存在这样的子数组,此时最小长度为INT_MAX,是不合理的,可以判断最小长度是否超过数组nums的长度,如果超过,则返回长度为0。

代码实现:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int left = 0, right = left;
        int min_len = INT_MAX;
        int sum = 0;
        while (right < nums.size()) {
            sum += nums[right];
            while (sum >= target) {
                min_len = std::min(min_len,right-left+1);
                sum -= nums[left];
                left++;
            }
            right++;
        }
        if (min_len > nums.size()) {
            min_len = 0;
        }
        return min_len;
    }
};

Leetcode 59.螺旋矩阵II
思路分析:
本人第一次看题并没有思路,画出9宫格和16宫格进行推演,能想到按螺旋的顺序给二维数组的元素逐个赋值,但并没想好代码如何写。以上是参考《代码随想录》视频后,写出来的。
本题的关键:
1.确定单个圈里每条边的左右边界,要确保边界值不重复遍历;
2.确定内外圈的关系,主要是起始点的坐标和边长发生了改变,相邻内外圈可建立联系;
3.区分n是奇数或偶数,如果是奇数,则最后一个元素需要单独赋值。
代码实现

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> result(n, vector<int>(n,0));
        int start_x = 0, start_y = 0;
        int loop = n / 2;
        int val = 1;
        int i = 0, j = 0;
        int offset = 1;
        while (loop) {
            i = start_x;
            j = start_y;
            for (j=start_y; j < start_y+n-offset;j++) {
                result[start_x][j] = val++;
            }
            for (i=start_x;i<start_x+n-offset;i++) {
                result[i][j] = val++;
            }
            for (;j>start_y;j--) {
                result[i][j] = val++;
            }
            for (;i>start_x;i--) {
                result[i][start_y] = val++;
            }
            start_x++;
            start_y++;
            offset+=2;
            loop--;
        }
        if (n%2 == 1) {
            result[n/2][n/2] = val;
        }
        return result;
    }
};

你可能感兴趣的:(代码随想录训练营,算法,leetcode,数据结构)