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

目录

  • Leetcode 977.有序数组平方
    • 遇到的困惑点
    • 双指针代码
  • Leetcode 209.长度最小的子数组
    • 滑动窗口技术
    • 遇到的困惑点
    • 代码实现
  • Leetcode 59.螺旋矩阵
    • 遇到的疑惑点
    • 新学习的知识
    • 代码实现
  • 参考文献

Leetcode 977.有序数组平方

遇到的困惑点

1.思维有点固化,还在想套用Leetcode.27题的双指针思路。但是发现时间复杂度上不能达到O(n),遂放弃。

双指针代码

#include 
#include
using namespace std;

void printVector(vector<int> v){
    int len = v.size();
    for(int i = 0; i < len; i++){
        cout<<v.at(i)<<" ";
    }
    cout<<endl;
}

void inputFunction(vector<int> &v){
    int inputArray[] = {-4,-1,0,3,10};
    int arraySize = sizeof(inputArray)/sizeof(inputArray[0]);
    for(int i = 0; i < arraySize;i++){
        v.push_back(inputArray[i]);
    }
}


class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        //先平方,在排序
        //平方操作
        int n = 0;
        int len = nums.size();
        vector<int> res(len);
        while(n < len){
            nums[n] = nums[n] * nums[n];
            n++;
        }
//        printVector(nums);
        //排序
        int leftPoint = 0;
        int rightPoint = len - 1;


        for(int i = len - 1; i >= 0;i--){
            if(nums[leftPoint] >= nums[rightPoint]){
                res[i] = nums[leftPoint];
                leftPoint++;
            }
            else{
                res[i] = nums[rightPoint];
                rightPoint--;
            }
        }

        /*while(len--){
            nums[len -1] = res[len -1];
        }*/
        return res;
    }
};




int main() {

    Solution s;
    vector<int> v;
    inputFunction(v);

    cout<<"输入数组:";
    printVector(v);
    
    cout<<"输出数组:";
    printVector(s.sortedSquares(v));

    return 0;
}

运行结果

D:\ProgramData\CPlusPlus\Trin2_LC977\cmake-build-debug\Trin2_LC977.exe
输入数组:-4 -1 0 3 10 
输出数组:0 1 9 16 100 

Leetcode 209.长度最小的子数组

滑动窗口技术

核心点
窗口的终止位置用外层循环移动窗口起始位置使用内层循环移动(虽然使用了双层循环,但是每个元素只使用了一次,所以时间复杂度仍是O(n))。窗口内的元素求和。
窗口滑动是,通过更新窗口起始位置实现的。

遇到的困惑点

1.滑动窗口的代码实现,之前没接触过。
2.在代码实现中关于终止位置使用外层循环,起始位置使用内层循环,窗口滑动的更新,这三个细节点要反复理解下

代码实现

#include 
#include

using namespace std;

void printVector(vector<int> v){
    int len = v.size();
    for(int i = 0; i < len; i++){
        cout<<v.at(i)<<" ";
    }
    cout<<endl;
}

void inputFunction(vector<int> &v){
    int inputArray[] = {2,3,1,2,4,3};
    int arraySize = sizeof(inputArray)/sizeof(inputArray[0]);
    for(int i = 0; i < arraySize;i++){
        v.push_back(inputArray[i]);
    }
}





class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT_MAX;
        int sum = 0;
        int startPoint = 0;//初始起始位置
        int subLength = 0;//滑动窗口的长度
        int endPoint;
//        cout<<"nums.size() = "<
        for(endPoint = 0;endPoint < nums.size();endPoint++){
            sum += nums[endPoint];
            while(sum >= target){
                subLength = (endPoint - startPoint +1);
//                result = subLength
                result = result<subLength ? result:subLength;
                sum -=nums[startPoint++];
//                startPoint++;//滑动窗口的精髓,存在大于等于的子序列后不断变更起始窗口位置。
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == INT_MAX ? 0 : result;
    }
};



int main() {
    Solution s;
    vector<int> v;
    inputFunction(v);
    cout<<"input array = ";
    printVector(v);

    int target = 7;
    int res = s.minSubArrayLen(target,v);
    cout<<"min short sublength = "<<res<<endl;

    return 0;
}

运行结果

D:\ProgramData\CPlusPlus\Trin2_LC209\cmake-build-debug\Trin2_LC209.exe
input array = 2 3 1 2 4 3 
min short sublength = 2

Process finished with exit code 0

算法部分可以通过Leetcode平台,但是在本地ide上运行时,无最小子序列,以及其他一些用例会出现数值大1的情况,还没发现问题在哪。

Leetcode 59.螺旋矩阵

遇到的疑惑点

1.螺旋矩阵的细节点在于循环不变量
2.i,j定义在循环的外侧,恰好实现自动更新每次初始位置。
3.关于转几圈的判断,以及特殊情况有中心元素,怎么处理。

新学习的知识

1.关于二维动态数组的创建初始化打印赋值
2.循环不变量思想的巩固

代码实现

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> v(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
        int xStart = 0,yStart = 0;
        int offset = 1;
        int count  = 1;
        int i,j;
        int loop = n/2;

        while(loop--){

            //上行
            for(j = yStart; j < n - offset;j++){
                v[xStart][j] = count++;
            }
            //右列
            for(i = xStart; i < n - offset;i++){
                v[i][j] = count++;
            }
            //下行
            for(; j > yStart;j--){
                v[i][j] = count++;
            }
            //左列
            for(; i > xStart;i--){
                v[i][j] = count++;
            }
            //后一圈开始前,起始位置要加1
            xStart++;
            yStart++;
            //
            offset++;

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

参考文献

https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

你可能感兴趣的:(算法,数据结构)