Leetcode---353周赛

周赛题目

2769. 找出最大的可达成数字

2770. 达到末尾下标所需的最大跳跃次数

2771. 构造最长非递减子数组

2772. 使数组中的所有元素都等于零

一、找出最大的可达成数字

Leetcode---353周赛_第1张图片

这题就是简单的不能在简单的简单题, 题目意思是:给你一个数num和操作数t,需要你在对num和x进行t次操作之后,使得x<=num,问这个初始x的最大值是多少?那很显然num不断+1,x不断-1,最后x==num这种情况下,x的初始值最大,代码如下

int theMaximumAchievableX(int num, int t){
    return num+2*t;
}

二、达到末尾下标所需的最大跳跃次数

Leetcode---353周赛_第2张图片

遇到这种从数组头跳到尾的跳跃问题,一般都是用动态规划,但是我们先不用动态规划,我们先用递归来想一想

1.确定递归参数及其返回值:根据题目,它要求从0到n的最大跳跃次数,我们就定义dfs(i)返回从0到i的最大跳跃次数(i表示下标)

2.确定递归的表达式:dfs(i)=max{dfs(k,i)+1}  (k

3.确定递归的边界边界和递归入口:

递归边界:i==0时,返回0,即理解为在一开始的跳跃次数是0,或者从0到0不需要跳跃

递归入口:dfs(n-1)

代码如下

//这个是一般的递归写法,会超时
int T;
int*Nums;
int dfs(int i){
    if(i==0)
        return 0;
    int res=INT_MIN;//这里给整形的最小值表示一种不可能的可能性,且不防止后面取较大值
    for(int k=0;k

那么如果我们一开始就知道用动态规划,我们应该怎么思考这道题?其实思考的过程和上面的递归神似,我们只要思考下面的三个问题:1.动规的数组的含义是什么?2.动规的递推表达式是什么?3.动规数组的初始化是什么?

参开上面代码我们不难回答上面三个问题:

1.f[i] 代表从0到i所需的最大跳跃次数

2.f[i] = max{ f[k] + 1 }   ( k < i )  条件为abs( f[i] - f[k] ) <= target

3.f[0] = 0 

代码就是上面的由递归翻译出的递推

大家可以自己去感悟感悟两种思考过程的联系和区别,对以后的做题还是很有帮助的

三、构造最长非递减子数组

Leetcode---353周赛_第3张图片

 其实这题和上面一题一样用递归来解决,我们还是需要(从后往前推)

1.确定递归的参数和返回值:我们需要确定第i个数字取nums1[i]还是nums2[i],所以我们需要两个参数,dfs(i,0/1),i代表当前位下标,0/1代表第i个数选的是哪个数组中的数,返回值代表子数组的最大长度

2.确定递归的表达式:dfs(i,0/1)=max{dfs(i-1,0/1)+1} 前提:符合条件

3.递归的边界和入口:边界条件:i==0,返回1 

代码如下

int **nums;
int*Nums1;
int*Nums2;
int**memo;
int dfs(int i,int j){
    if(i==0)
        return 1;
    if(memo[i][j]!=-1)
        return memo[i][j];
    int res=1;
    if(Nums1[i-1]<=nums[j][i])
        res=fmax(res,dfs(i-1,0)+1);
    if(Nums2[i-1]<=nums[j][i])
        res=fmax(res,dfs(i-1,1)+1);
    return memo[i][j]=res;
}
int maxNonDecreasingLength(int* nums1, int nums1Size, int* nums2, int nums2Size){
    nums=(int**)malloc(sizeof(int*)*2);
    nums[0]=nums1,nums[1]=nums2;
    Nums1=nums1,Nums2=nums2;
    memo=(int**)malloc(sizeof(int*)*nums1Size);
    for(int i=0;i

 四、使数组中的所有元素都等于零

Leetcode---353周赛_第4张图片

这题看到对一段区间进行加减的操作就要想到差分数组,那么差分数组是啥?下面举个例子来带领大家了解一下 

Leetcode---353周赛_第5张图片

 了解了差分数组之后,这题其实就迎刃而解了,补充一点当差分数组全为0时,原数组就是全0

代码如下

bool checkArray(int* nums, int numsSize, int k){
    int f[numsSize+1];//防止x下面的i+k越界
    memset(f,0,sizeof(f));
    f[0]=nums[0];
    for(int i=1;i0){
            f[i+k]+=f[i];
            f[i]=0;
        }
    }
    for(int i=0;i<=numsSize;i++){
        if(f[i]!=0)
            return false;
    }
    return true;
}

你可能感兴趣的:(leetcode,算法,职场和发展)