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

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

  1. 有序数组的平方977

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep

C语言一刷:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
/*

//暴力
*returnSize = numsSize;//*****
int i,j,t;

for(i=0;i<numsSize;i++)
{
    nums[i]=nums[i]*nums[i];

}

for(i=0;i<numsSize-1;i++)
  {
      t=i;
      for (j=i+1;j<numsSize;j++)
        if(nums[j]<nums[t])
            {
                t=j;
            }
        
        if(i!=t)
        {
            int tem = nums[i];
            nums[i] =nums [t];
            nums[t] = tem;
        }
  }  


return nums;

*/  
//双指针法
*returnSize = numsSize;
int i, left,right;

int* a = (int*)malloc(sizeof(int) * numsSize);
left =0;
right=numsSize-1;
for(i=numsSize-1;i>=0;i--)
{
if(nums[left]*nums[left]>nums[right]*nums[right])
    {
      a[i]=nums[left]*nums[left];
      left++;  
    }
else
    {
      a[i]=nums[right]*nums[right];
      right--;  
    }

}
return a;



}

C++二刷:

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

总结
在有序数组中由负到正依次排序,本题求数组中element的平方排序,从一开始就是应用双指针法的思路来解决这道题,由于是由小到大,我就从数组尾部开始比大小,之后来赋值new element,最后得出结果。(这题在江苏理工的笃行杯竞赛里有一道)eg:就像你异世界的战力排行,魔王(负数)和人类(正数)这边,你把正义邪恶的光环去掉,就把他们的战力都平方,然后左右两极开始,在新的战力表里末尾降序战力值。 最后返回新的战力表。

  1. 长度最小的子数组 209

题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
文章讲解:https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE

C语言一刷:

int minSubArrayLen(int target, int* nums, int numsSize) {
int sum=0;
int j=0;
int l=0;
int flag=0;
int min=numsSize;
for(int i=0;i<numsSize;i++)
{
    sum=sum+nums[i];
    while(sum>=target)
    {   
        l=i-j+1;
        if(l<min)
        min=l;
        sum=sum-nums[j++];
        flag=1;

    }
}

if (flag!=1)
min=0;

return min;

}
/*
//暴力
int minSubArrayLen(int target, int* nums, int numsSize){
    //初始化最小长度为INT_MAX
    int minLength = INT_MAX;
    int sum;

    int left, right;
    for(left = 0; left < numsSize; ++left) {
        //每次遍历都清零sum,计算当前位置后和>=target的子数组的长度
        sum = 0;
        //从left开始,sum中添加元素
        for(right = left; right < numsSize; ++right) {
            sum += nums[right];
            //若加入当前元素后,和大于target,则更新minLength
            if(sum >= target) {
                int subLength = right - left + 1;
                minLength = minLength < subLength ? minLength : subLength;
            }
        }
    }
    //若minLength不为INT_MAX,则返回minLnegth
    return minLength == INT_MAX ? 0 : minLength;
}
*/

C++二刷:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {

        int i,resultlength,length,sum;
        resultlength=INT32_MAX;
        sum=0;
        for(int j=0;j<nums.size();j++)
        {
            sum+=nums[j];
            while(sum>=target)
            {
                    length=j-i+1;
                    resultlength=min(resultlength,length);
                    sum-=nums[i++];
                
            }
        }

        return resultlength==INT32_MAX?0:resultlength;
    }
};

总结
我自己用滑动窗口的算法解了一下,重要的还是里面的while的作用,分清起始点和终点的区别(本人是起始j,终点i),首先一开始要统计sum,然后你到后面要有与target作比较,在求最小中也就是while的功能,并比较其最小的数值。eg:就像你打吃鸡类的游戏,你们队在梅花桩(圈子中心),然后安全区慢慢缩小,最后你们在房区,决赛圈在前面的空地。你们之中有人大喊:“压缩到最后!涌出去!!!”。(最后对min的return要注意)

  1. 螺旋矩阵II 59

题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/

C语言一刷:

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes) {
    
    *returnSize = n;
    *returnColumnSizes = (int*)malloc(sizeof(int) * n);
    //初始化返回结果数组ans
    int** ans = (int**)malloc(sizeof(int*) * n);
    int i;
    for(i = 0; i < n; i++) {
        ans[i] = (int*)malloc(sizeof(int) * n);
        (*returnColumnSizes)[i] = n;
    }


    int x,y,k,c,loop;
    x=0;
    y=0;
    k=1;
    c=1;
    loop=n/2;
    while(loop)
    {
      int  i=x;
      int  j=y;
        for(;j<n-k;j++)
            ans[i][j]=c++;
        for(; i<n-k;i++)
            ans[i][j]=c++;
        for(;j>y;j--)
            ans[i][j]=c++;
        for(;i>x;i--)
            ans[i][j]=c++;
        
        x++;
        y++;
        k++;
        loop--;
    }
    if(n%2==1)
    {
        ans[x][y]=c;
    }    

    return ans;

}

C++二刷:
*其中一开始有个mylist的初始化,那没啥用不如直接,int size=0; Linknode dummyhead=new Linknode(0);
那玩意就是花架子,不如直接全局写。


class MyLinkedList {
public:
// 初始化链表
    struct Linknode
    {
        int val;
        Linknode* next;

        Linknode(int val):val(val),next(nullptr){}
    };

int size=0;
 Linknode* dummyhead=new Linknode(0);
    

// 获取到第index个节点数值,如果index是非法数值直接返回-1, 注意index是从0开始的,第0个节点就是头结点
    
    int get(int index) {

        if(index>(size-1)||index<0)
        return -1;

        Linknode* cur=dummyhead->next;
        while(index--)// 如果--index 就会陷入死循环
        {
            cur=cur->next;
        }
        return cur->val;
    }
 // 在链表最前面插入一个节点,插入完成后,新插入的节点为链表的新的头结点    
  void addAtHead(int val) {
        
        Linknode* newode=new Linknode(val);

        newode->next=dummyhead->next;
        dummyhead->next=newode;

        size++;

    }
// 在链表最后面添加一个节点    
    void addAtTail(int val) {
        Linknode* lastnode=new Linknode(val);

        Linknode* cur=dummyhead;

        while(cur->next!=nullptr)
        {
            cur=cur->next;
        }
        cur->next=lastnode;
        size++;
    }

// 在第index个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
// 如果index 等于链表的长度,则说明是新插入的节点为链表的尾结点
// 如果index大于链表的长度,则返回空
// 如果index小于0,则在头部插入节点    
    void addAtIndex(int index, int val) {
        if(index>size) return;
        if(index<0) index=0;

        Linknode* newnode=new Linknode(val);
        Linknode* cur=dummyhead;

        while(index--)
        {
            cur=cur->next;
        }

        newnode->next=cur->next;
        cur->next=newnode;

        size++;

    }
//删除第index个节点,如果index 大于等于链表的长度,直接return,注意index是从0开始的    
    void deleteAtIndex(int index) {

        if(index>=size||index<0)
        return;

        Linknode* cur=dummyhead;

        while(index--)
        {
            cur=cur->next;
        }


        Linknode* tmp=cur->next;
        cur->next=cur->next->next;

        delete tmp;

        tmp=nullptr;

        size--;

    }


};



/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

总结
这题是对矩阵的考察,听说是有不少企业把其当面试题。在道题求解,就是【)的区间,然后分右下左上的分别4个方向来解题,4个要统一的区间,不然会搞混淆。while里面的loop是由于每次右下左上也就是一圈,一圈会占两行两列,所以就n/2。注意在最后,要对n进行奇偶的判定不然奇数其中间就空元素。eg:四个方向,写一程序,每次占两行两列,然后/2,最后别忘奇条件。(画矩形)

  • 25
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值