【数据结构刷题集】数组

😽 PREFACE
🎁欢迎各位→点赞 👍 + 收藏 ⭐ + 评论 📝
📢系列专栏: 数据结构刷题集
🔊本专栏涉及到题目是数据结构专栏的补充与应用,只更新相关题目,旨在帮助提高代码熟练度
💪 种一棵树最好是十年前其次是现在

轮转数组

题目链接:https://leetcode.cn/problems/rotate-array/

三次反转

/*
解题思路:使用三次逆转法,让数组旋转k次
1. 逆转子数组[0, k - 1]
2. 逆转子数组[k, size - 1]
3. 先整体逆转
*/

void swap(int* a,int* b)
{
    int t=0;
    t=*a;
    *a=*b;
    *b=t;
}
void reverse(int* begin,int* end)
{
    while(begin<end)
    {
        swap(begin,end);
        begin++;
        end--;
    }
}


void rotate(int* nums, int numsSize, int k){
    k%=numsSize;
    reverse(nums,nums+numsSize-1-k);
    reverse(nums+numsSize-k,nums+numsSize-1);
    reverse(nums,nums+numsSize-1);
    return 0;
}

消失的数字

题目链接:https://leetcode.cn/problems/missing-number-lcci/

int missingNumber(int* nums, int numsSize){
    int sum=0;
    for(int i=0;i<numsSize+1;i++)
    {
        sum+=i;
    }
    for(int i=0;i<numsSize;i++)
    {
        sum-=nums[i];
    }
    return sum;
}

移除元素

题目链接:https://leetcode.cn/problems/remove-element/submissions/

法一:暴力法

int removeElement(int* nums, int numsSize, int val){
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]==val)
        {
            for(int j=i+1;j<numsSize;j++)
            {
                nums[j-1]=nums[j];
            }
            i--;
            numsSize--;
        }
    }
    return numsSize;
}

法二:双指针法

int removeElement(int* nums, int numsSize, int val){
    int src=0,dst=0;
    while(src<numsSize)
    {
        if(nums[src]!=val)
        {
            nums[dst++]=nums[src++];
        }
        else
        {
            src++;
        }
    }
    return dst;
}

删除排序数组中的重复项

题目链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array/

int removeDuplicates(int* nums, int numsSize){
    if(numsSize==0)
    {
        return 0;
    }
    int i=0,j=1,dst=0;
    while(j<numsSize)
    {
        if(nums[i]==nums[j])
        {
            ++j;
        }
        else
        {
            nums[dst]=nums[i];
            ++dst;
            i=j;
            ++j;
        }
    }
    nums[dst]=nums[i];
    ++dst;
    return dst;
}

合并两个有序数组

题目链接:https://leetcode.cn/problems/merge-sorted-array/

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    int end1=m-1,end2=n-1;
    int end=m+n-1;
    while(end1>=0&&end2>=0)
    {
        if(nums1[end1]>nums2[end2])
        {
            nums1[end--]=nums1[end1--];
        }
        else
        {
            nums1[end--]=nums2[end2--];
        }
    }
    while(end2>=0)
    {
        nums1[end--]=nums2[end2--];
    }
}

长度最小的子数组

题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/

法一:暴力法

int minSubArrayLen(int target, int* nums, int numsSize){
    int res=INT32_MAX;//返回int类型最大的值
    int sum=0;//子数组元素之和
    int len=0;//子数组的长度
    for(int i=0;i<numsSize;i++)
    {
        sum=0;
        for(int j=i;j<numsSize;j++)
        {
            sum+=nums[j];
            if(sum>=target)//更新res
            {
                len=j-i+1;//获取子数组的长度
                res=res<len?res:len;
                break;
            }
        }
    }
    return res==INT32_MAX?0:res;
}

法二:滑动窗口

int minSubArrayLen(int target, int* nums, int numsSize){
    int res=INT32_MAX;
    int sum=0;//滑动窗口的数值之和
    int i=0;//滑动窗口的起始位置
    int len=0;//滑动窗口的长度
    for(int j=0;j<numsSize;j++)
    {
        sum+=nums[j];
        while(sum>=target)
        {
            len=(j-i+1);//获取子数组的长度
            res=res<len?res:len;
            sum-=nums[i++];
        }
    }
    return res==INT32_MAX?0:res;
}

螺旋数组

题目链接:https://leetcode.cn/problems/spiral-matrix-ii/

int** generateMatrix(int n, int* returnSize, int** returnColumnSizes)
{
    int**res=(int**)malloc(sizeof(int*)*n);
    *returnSize=n;
    *returnColumnSizes=(int*)malloc(sizeof(int)*n);
    for(int i=0;i<n;i++) 
    {
        res[i]=malloc(sizeof(int)*n);
        memset(res[i],0,sizeof(int)*n);
        (*returnColumnSizes)[i]=n;
    }
    
    int startx=0,starty=0;//每循环一圈的起始位置
    int loop=n/2;//每一圈循环几次
    int mid=n/2;//矩阵中间位置
    int count=1;//给矩阵的每一个空格赋值
    int offset=1;//每一圈循环都需要控制每一条边遍历的长度
    int i,j;
    while(loop--)
    {
        i=startx;
        j=starty;
        
        //上行从左到右
        for(j=starty;j<starty+n-offset;j++)
        {
            res[startx][j]=count++;
        }

        //右列从上到下
        for(i=startx;i<startx+n-offset;i++)
        {
            res[i][j]=count++;
        }


        //下行从右到左
        for(;j>starty;j--)
        {
            res[i][j]=count++;
        }

        //左列从下到上
        for(;i>startx;i--)
        {
            res[i][j]=count++;
        }

        //第二圈开始的时候,起始位置要各自加1
        startx++;
        starty++;
        offset=offset+2;//用于控制每一圈中每一条边遍历的长度
    }
    if(n%2)//如果是奇数,则需要单独给矩阵最中间的位置赋值
    {
        res[mid][mid]=count;
    }
    return res;
}
  • 46
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 52
    评论
评论 52
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值