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

977.有序数组的平方

 题目:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

 暴力解

思路:

首先就想到每个数组平方之后,在进行快速排序即可。

完整代码

#include <stdio.h>


int Partition(int A[],int low,int high);
void QuickSort(int A[],int low,int high);
int* sortedSquares(int* nums, int numsSize, int* returnSize);
int main()
{
    int nums[5] = {-7,-3,2,3,11};
    int lenth;
    int *arr;
    arr = sortedSquares(nums,5,&lenth);
    for(int i=0;i<lenth;i++)
        printf("%4d",arr[i]);
    return 0;
}

/***************************************************************
** 功能:     每个元素平方后排序
** 参数:	  nums:传入数组首地址    numsSize:数组大小    returnSize:返回数组大小
** 返回值:    arr:返回平方后递增数组
****************************************************************/
/*暴力解法*/
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    int *arr = NULL;
    *returnSize = numsSize;
    arr = (int *)malloc(sizeof(int) * numsSize);
    for(int i=0;i<numsSize;i++)
    {
        arr[i] = nums[i] * nums[i];
    }
    QuickSort(arr,0,numsSize-1);
    return arr;
}
void QuickSort(int A[],int low,int high)
{
    int pivotpos;
    if(low<high)
    {
        pivotpos = Partition(A,low,high);
        QuickSort(A,low,pivotpos-1);
        QuickSort(A,pivotpos+1,high);
    }
}
int Partition(int A[],int low,int high)
{
    int pivot = A[low];
    while(low<high)
    {
        while(low<high&&A[high]>=pivot) --high;
        A[low] = A[high];
        while (low<high&&A[low]<=pivot) ++low;
        A[high] = A[low];
    }
    A[low] = pivot;
    return low;
}

双指针方法

思路:

该数组是非递减存在负数的数组,所以最大的元素一定在两边,从两边开始取数进行平方,比较谁更大,然后放在新的数组中,依次向中间靠拢直到退出循环。

完整代码 

#include <stdio.h>

int* sortedSquares(int* nums, int numsSize, int* returnSize);
int main(void)
{
    int nums[5] = {-4,-1,0,3,10};
    int lenth;
    int *arr;
    arr = sortedSquares(nums,5,&lenth);
    for(int i=0;i<lenth;i++)
        printf("%4d",arr[i]);
    return 0;
}

/***************************************************************
** 功能:     每个元素平方后排序
** 参数:	  nums:传入数组首地址    numsSize:数组大小    returnSize:返回数组大小
** 返回值:    arr:返回平方后递增数组
****************************************************************/
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    *returnSize = numsSize;//返回数组大小等于传入数组大小
    int *arr = (int *)malloc(sizeof (int) * numsSize);//申请与传入数组大小相等的数组空间
    int low = 0,high = numsSize-1;
    int k = numsSize - 1;//新数组下表,倒序开始
    while(low<=high)
    {
        //如果low的平方大于high的平方
        if( (nums[low]*nums[low]) > (nums[high]*nums[high]) )
        {
            arr[k] = (nums[low]*nums[low]);
            low++;//low向中间移动
        }
        else//这里包含相等的情况
        {
            arr[k] = (nums[high]*nums[high]);
            high--;//high向中间移动
        }
        k--;//数组下标前移
    }
    return arr;
}

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

暴力解

思路 :

用一个for循环作为起始位置作为外层循环,另一个for循环收集求和,若大于给定值则收集区间长度并且跳出内层循环,直到外层循环遍历整个数组结束,最终取最小值返回,若没有则返回0.

 完整代码

#include <stdio.h>

int minSubArrayLen(int target, int* nums, int numsSize);
int main()
{
    int arr[6] = {2,3,1,2,4,3};
    printf("%d",minSubArrayLen(7,arr,6));
    return 0;
}


/***************************************************************
** 功能:     寻找最小的子长度数组
** 参数:	  target:目标值    nums:传入的数组    numsSize:数组大小
** 返回值:    0:表示没有符合的子数组     非0:表示子数组长度
****************************************************************/
int minSubArrayLen(int target, int* nums, int numsSize) {
    int sum = 0;
    int result = numsSize;
    for(int i = 0;i < numsSize;i++)
    {
        sum = sum + nums[i];
        //判断是否存在子数组
        if(sum >= target)
            break;
    }
    if(sum<target)
        return 0;
    for(int i = 0;i < numsSize;i++)
    {
        sum = 0;
        for(int j = i;j < numsSize;j++)
        {
            sum = sum + nums[j];
            if(sum >= target)
            {
                //如果result>该长度,则返回该长度,否则不变
                result = ( result > (j - i + 1) ) ? ( j - i + 1 ) : result;
                //找到之后就结束本次循环,因为在向后增加还是符合题意,只不过不可能是最小
                break;
            }
        }
    }
    return result;
}

滑动窗口解法

思路:

难点是对谁进行for循环,假设对i进行for循环会发现,j也要for循环才能后使得sum的值增加,这样又会回到暴力解,所以我们只对j进行for循环,还有一个问题就是i的移动到底是移动一次还是一直移动,很明显是一直移动直到不符合题意,

完整代码 

#include <stdio.h>

int minSubArrayLen(int target, int* nums, int numsSize);
int main()
{
    int arr[6] = {2,3,1,2,4,3};
    printf("%d",minSubArrayLen(7,arr,6));
    return 0;
}
/***************************************************************
** 功能:     寻找最小的子长度数组
** 参数:	  target:目标值    nums:传入的数组    numsSize:数组大小
** 返回值:    0:表示没有符合的子数组     非0:表示子数组长度
****************************************************************/
int minSubArrayLen(int target, int* nums, int numsSize) {
    int i = 0,sum = 0,result = numsSize;
    _Bool flag = 0;//用来判断整个数组是否符合题意
    for(int j=0;j<numsSize;j++)
    {
        sum = sum + nums[j];
        while(sum>=target)
        {
            //符合题意时,起始指针减起始指针的数值,直到不符合题意
            sum = sum - nums[i];
            //判断是否是最小子数组
            if( result > (j-i+1) )
            {
                result = j-i+1;
            }
            //起始指针右移动
            i++;
            //有一次符合就说明该数组一定存在最小子数组,flag设置为1
            flag = 1;
        }
    }
    if(flag == 1)
        return result;
    else
        return 0;
}

 59.螺旋矩阵II

 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

 思路

代码

int** generateMatrix(int n, int* returnSize, int** returnColumnSizes) {
*returnSize = n; // 设置返回数组的大小
// 分配返回数组的列大小
*returnColumnSizes = (int*)malloc(sizeof(int) * n);

// 分配返回数组的空间
int **arr = (int **)malloc(sizeof (int*) * n);

int offset = 1; // 偏移量,用于控制每一圈的起始位置
int x = 0; // 当前位置的行坐标
int y = 0; // 当前位置的列坐标
int count = 1; // 当前要填入的数字
int i = 0, j = 0; // 循环计数变量
int loop = n/2; // 控制循环次数,一共需要循环n/2次

// 分配返回数组的每一行的空间,并设置列大小
for(i = 0; i < n; i++) {
    arr[i] = (int*)malloc(sizeof(int) * n);
    (*returnColumnSizes)[i] = n;
}

// 根据循环次数进行填充
while(loop)
{
    // 填充当前圈的上边
    for(j=y;j<n-offset;j++)
        arr[x][j] = count++;

    // 填充当前圈的右边
    for(i=x;i<n-offset;i++)
        arr[i][j] = count++;

    // 填充当前圈的下边
    for(;j>y;j--)
        arr[i][j] = count++;

    // 填充当前圈的左边
    for(;i>x;i--)
        arr[i][j] = count++;

    // 更新起始位置和偏移量
    x++;
    y++;
    offset--;
    loop--;
}

// 如果n为奇数,最后一个位置需要单独填充
if(n%2 != 0)
    arr[x][y] = count;

return arr; // 返回生成的数组

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值