LeetCode 第41~43题

目录

LeetCode 第41题:缺失的第一个正数

 LeetCode 第42题:接雨水

 LeetCode 第43题:字符串相乘

LeetCode 第41题:缺失的第一个正数

题目描述:

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

难度:困难

题目链接:41. 缺失的第一个正数 - 力扣(LeetCode)

 示例1:

输入:nums = [1,2,0]
输出:3
解释:数字 1 和 2 都出现了,所以最小的缺失正整数是 3

示例2:

输入:nums = [3,4,-1,1]
输出:2
解释:1 出现了,但 2 没有出现,所以最小的缺失正整数是 2

 示例3:

输入:nums = [7,8,9,11,12]
输出:1
解释:最小的正整数 1 没有出现,所以答案是 1

提示:

1 <= nums.length <= 5 * 10^5
-2^31 <= nums[i] <= 2^31 - 1

解题思路:

方法一:原地哈希法

  •  数组长度为n,那么缺失的第一个正整数一定在【1,n+1】范围内。
  • 可以将数字k放到数组的第k-1个位置上
  • 遍历完成后,第一个不在对应位置上的数字的下标加1就是答案
int firstMissingPositive(int* nums,int numsSize)
{
    //将数组当中的非正数改为正数
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]<=0)  nums[i] = numsSize+1;
    }
    //从1开始,如果存在数字将对应位置的数字标记为负数
    for(int i=0;i<numsSize;i++)
    {
        int num = abs(nums[i]);
        if(num<=numsSize)  nums[num-1] = -abs(nums[num-1]);

    }
    //返回第一个没有出现的整数,对应于数组的第一个正数的位置+1
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]>0)  return i+1;

    }
    //如果上述for循环没有return,则说明对应位置都有正整数,则返回下一个位置对应的正整数
    return numsSize+1;
}

方法二:置换法

int firstMissingPositive(int* nums,int numsSize)
{
    for(int i=0;i<numsSize;i++)
   {
       //当nums[i]在数组索引范围内,并且数字对应的索引-1的位置没有出现该数字的时候
        //交换两者的位置
       while(nums[i]>0 && nums[i]<=numsSize && nums[nums[i]-1]!=nums[i])
            {
                 int t = nums[nums[i]-1];
                 nums[nums[i]-1] = nums[i];
                 nums[i]=t;

            }
        for(int i=0;i<numsSize;i++)
        {
            if(nums[i]!=i+1)  return i+1;
            
        }
        return numsSize+1;
    }
}

 LeetCode 第42题:接雨水

题目描述:

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

难度:困难

题目链接42. 接雨水 - 力扣(LeetCode)

示例1:

 

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

示例2:

输入:height = [4,2,0,3,2,5]
输出:9

提示:

n == height.length
1 <= n <= 2 * 10^4
0 <= height[i] <= 10^5

 解题思路:双指针

  • 使用左右指针分别指向数组两端,每个位置能接的雨水量=min(左侧最大高度,右侧最大高度)-当前高度
  • 每次移动较小的那一侧的指针
  • 累加当前位置能接的雨水量 
int Trap(int* height,int numsSize)
{
    if(height==null || numsSize<3)  return 0;
    int left = 0,right = numsSize-1;
    int leftMax = 0,rightMax = 0;
    int result = 0;
    while(left<right)
    {
    //更新左右两侧的最大高度
     leftMax = fmax(leftMax,height[left]);
     rightMax = fmax(rightMax,height[right]);
    //移动较小的一侧
     if(leftMax<rightMax) 
     {
        result = result+leftMax - height[left];
        left++;
    }
    else
    {
        result = result+rightMax - height[right];
        right--;
    }
    }
    return result;
}

 LeetCode 第43题:字符串相乘

题目描述:

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

难度:中等

题目链接:43. 字符串相乘 - 力扣(LeetCode)

示例1:

输入:num1 = "2", num2 = "3"
输出:"6"

 示例2:

输入:num1 = "123", num2 = "456"
输出:"56088"

提示:

1 <= num1.length, num2.length <= 200
num1 和 num2 只能由数字组成
num1 和 num2 都不包含任何前导零,除了数字0本身

解题思路:竖乘法

  •  两个长度分别为m和n的数字相乘,结果最多有m+n位
  • 从个位开始,逐位相乘并累加到对应位置
  • 处理进位
  • 去除前导零,转换为字符串 
string Multiply(char* num1,char* num2)
{
    if(num1==“0” || num2=="0")  return "0";
    int m = strlen(num1),n=strlen(num2);
    char* result = (char*)malloc(m+n+1);
    for(int i=m-1;i>=0;i--)
    {
        for(int j=n-1;j>=0;j--)
        {
            int mul = (num1[i]-'0')*(num2[j]-'0')
            //定义高位和低位
            int p1=i+j,p2=i+j+1;
            //叠加到结果数组
            int sum = mul+result[p2];
            result[p2] = sum %10;
            result[p1] = result[p1]+sum/10;
        }
    }
    //在result数组中找到第一个不为0的数字,并开始输出
    bool flag=true;
    char* str = (char*)malloc(m+n+1);
    for(int k=m+n;k>=0;k--)
    {
        if(result[k]==0 && flag==true) continue;
        flag =false;
        str[k]=result[k];
    }
    return strlen(str)==0 ? "0" : str;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值