【刷题记录2】算法|数据结构|C/C++

今天是2022/2/28 开第二层楼了


1~50题https://blog.csdn.net/Sui_Chris/article/details/122908486?spm=1001.2014.3001.5502


51.leetcode-55. 跳跃游戏

📅:22/2/28🥂

📌:dp|迭代

bool canJump(int* nums, int numsSize){
    int end=numsSize-1;
    for(int i=numsSize-2;i>=0;i--)
    {
        if(end-i<=nums[i])
        {
            end=i;
        }
    }
    if(!end)return true;
    return false;
}

啊~有点没搞懂呜呜😭

自己琢磨以下写了个新的 

bool canJump(int* nums, int numsSize){
    int head=0,end=0;
    for(;head<numsSize&&head<=end;head++)
    {
        end<head+nums[head]?end=nums[head]+head:end;
        if(end>=numsSize-1)return true;
    }
    return false;
}

52.leetcode-213. 打家劫舍 II

📅:22/3/2🥂

📌:dp|迭代

int rob(int* nums, int numsSize){
    if(numsSize==1)return nums[0];
    else if (numsSize==2)return fmax(nums[0],nums[1]);
    int *dp=(int*)malloc(sizeof(int)*numsSize);
    //注意初始化不要初始两位啊!
    dp[0]=nums[0],dp[1]=fmax(nums[0],nums[1]);
    int *dp2=(int*)malloc(sizeof(int)*numsSize);
    dp2[0]=0,dp2[1]=nums[1];
    //一定不偷最后一家
    for(int i=2;i<numsSize-1;i++)
    {
        dp[i] = fmax(dp[i-1],dp[i-2]+nums[i]);
    }
    //一定不偷第一家
    for(int i=2;i<numsSize;i++)
    {
        dp2[i] = fmax(dp2[i-1],dp2[i-2]+nums[i]);
    }
    return fmax(dp[numsSize-2],dp2[numsSize-1]);
}

 争取三月种完草~哈哈哈哈给自己立一个小目标,想换一个力扣的卫衣!

53.leetcode-740. 删除并获得点数

📅:22/3/2🥂

📌:dp|迭代

int deleteAndEarn(int* nums, int numsSize){
    int tong[10001]={0},max=nums[0],min=nums[0];
    for(int i=0;i<numsSize;i++)
    {
        tong[nums[i]]+=nums[i];
        max<nums[i]?max=nums[i]:max;
        min>nums[i]?min=nums[i]:min;
    }
    if(max-min<=1)return tong[max];
    int dp2,dp0=tong[min],dp1=fmax(dp0,tong[min+1]);
    for(int i=min+2;i<=max;i++)
    {
        dp2=fmax(dp0+tong[i],dp1);
        dp0=dp1;
        dp1=dp2;
    }
    return dp2;
}

 注意读题:获得nums[i]的点数时,nums[i]-1和nums[i]+1的所有数都会被删掉!就是没有点数!

那样就等于是打家劫舍:不可以偷相邻的房间。

54.leetcode-28. 实现 strStr()

 📅:22/3/2🥂

📌:KMP|迭代

int strStr(char * haystack, char * needle){
    if(!strlen(needle))return 0;
    else if(strlen(haystack)<strlen(needle))return -1;
    int *next=(int*)malloc(sizeof(int)*strlen(needle));
    next[0]=-1;
    int j=0,k=-1; 
    while (j<strlen(needle)-1) 
	{	
		if (k==-1 || needle[j]==needle[k]) 	//k为-1或比较的字符相等时
		{	
			j++;k++; 
			next[j]=k;
       	}
       	else
		{
			k=next[k];//?
        }
    }
    for(int i=0,j=0;i<strlen(haystack);)
    {
        if(needle[j]==haystack[i])j++,i++;
        else if(next[j]!=-1)
        {
            j=next[j];//此处的i还要和needle[next[j]]匹配,不能动
        }  
        else{
            j=0;i++;
        }
        if(j==strlen(needle))return i-j;
    }
    return -1;   
}

昨天看了一个下午的KMP…… 

55.leetcode-45. 跳跃游戏 II

 📅:22/3/3🍦

📌:贪心

O(N^{2})

int jump(int* nums, int numsSize){
    int *step=(int*)malloc(sizeof(int)*numsSize),walk=0;
    //记录每一个格子可以跳到的最大格子数
    for(int i=0;i<numsSize;i++)
    {
        step[i]=nums[i]+i;
    }
    //从后往前跳
    for(int end=numsSize-1;end>0;walk++)
    {
        //从前往后找大于end的
        for(int i=0;i<end;i++)
        {
            if(step[i]>=end)
            {
                end=i;
                break;
            }
        }
    }
    return walk;
}

O(N)

int jump(int* nums, int numsSize){
    int broud=nums[0],maxbroud=0,step=0;
    for(int i=1;i<numsSize;i++)
    {
        maxbroud<nums[i]+i?maxbroud=nums[i]+i:maxbroud;
        if(i==broud || i==numsSize-1)
        {
            step++;
            broud=maxbroud;
        }
    }
    return step;
}

到达边界的时候,更新边界(更新为旧边界之前能到达的最大的位置)

由于新边界跳跃点-旧边界之间已经遍历过,都没有大于新边界的,所以i不用回溯

 56.leetcode-1133. 最大唯一数

 📅:22/3/4🍦

📌:桶排序

int largestUniqueNumber(int* nums, int numsSize){
    int tong[1001]={0},max=nums[0];
    for(int i=0;i<numsSize;i++)
    {
        tong[nums[i]]++;
        max<nums[i]?max=nums[i]:max;
    }
    for(int i=max;i>=0;i--)
    {
        if(tong[i]==1)return i;
    }
    return -1;
}

 刚刚写一道题dp写了一个半小时调不出来……我吐了呜呜QAQ

只能再随便写一道简单的……勉强打上卡

57.leetcode-1567. 乘积为正数的最长子数组长度

 📅:22/3/4🍦

📌:dp|分类讨论

int getMaxLen(int* nums, int numsSize){
    int *dpN,*dpP,max;
    dpN=(int*)malloc(sizeof(int)*numsSize);
    dpP=(int*)malloc(sizeof(int)*numsSize);
    if(nums[0]>0)
    {
        dpN[0]=0;
        dpP[0]=1;
    }
    else if(!nums[0])
    {
        dpP[0]=0;
        dpN[0]=0;
    }
    else
    {
        dpP[0]=0;
        dpN[0]=1;
    }
    max=dpP[0];
    for(int i=1;i<numsSize;i++)
    {
        if(nums[i]<0)
        {
            dpP[i]=dpN[i-1]>0?dpN[i-1]+1:0;
            dpN[i]=dpP[i-1]+1;
        }
        else if(nums[i]>0)
        {
            dpP[i]=dpP[i-1]+1;
            dpN[i]=dpN[i-1]>0?dpN[i-1]+1:0;
        }
        else
        {
            dpN[i]=0;
            dpP[i]=0;
        }
        max<dpP[i]?max=dpP[i]:max;
    }
    return max;
}

nums[i]<0:

        dpNegative[i]=dpPositive[i-1]+1

        

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值