LeetCode 热题 100 Day04

文章讲述了两个LeetCode题目,一个是计算除自身外数组元素的乘积,涉及特殊处理0元素;另一个是寻找数组中缺失的第一个正整数,通过标记和置换策略解决。两题都分析了时间复杂度和空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组系列问题

Leetcode 238. 除自身以外数组的乘积【中等】

题意理解

        一个整数数组,求每个位置上出该元素外其余元素的乘积。

        我们可以先求出所有元素的乘积,再除以当前位置的元素即为所求。

        特别的是0元素,0不能做被除数,所以对于0元素需要额外的讨论。

解题思路

        使用product计算所有非零元素的和,使用zeroCount统计0元素的个数

        用result[] 数组来统计结果

        zeroCount==0时,result[i]=product/nums[i]

        zeroCount==1时,除了0元素对应的result[i]=product外,其余result[i]=0

        zeroCount==2时,剩余数中总有一个0元素,故result[i]=0

1.解题

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int len=nums.length;
        int zeroCount=0;
        int product=1;
        for(int i=0;i<len;i++){
            if(nums[i]==0){
                zeroCount++;
            }else{
                product*=nums[i];
            }
        }
        int[] result=new int[len];
        for(int i=0;i<len;i++){
            if(zeroCount==0){
                result[i]=product/nums[i];
            }else if(zeroCount>1){
                result[i]=0;
            }else if(zeroCount==1){
                if(nums[i]==0){
                    result[i]=product;
                }else{
                    result[i]=0;
                }
            }
        }
        return result;
    }
}

2.复杂度分析

时间复杂度: O(n)  遍历数组的时间

空间复杂度: O(n)  数组的空间损耗

Leetcode 41. 缺失的第一个正数【困难】

题意理解

        数组未排序,其中是否有最小正整数

        这个题目有个非常巧妙的地方。一个长度为n的数组,求最小出现的正整数。

        则如果这个数组中不存在缺失的最小正整数,则其应该存储的是1-n的n个正整数。

        当且仅当数组中存在<1或>n的数时,肯定有某个连续的地方被打断了。

解题思路

        1.标记出现的元素

        如果nums中没有1,则缺失的第一个元素就是1

        若nums中包含1,此时,将nums中<1||>n的元素替换为1

        从头开始遍历数组,其中,某个元素出现,则将对应位置(i-1)的元素置换为负数。

        如果当前位置已经是负数,则对应位置仍保留位负数。

        最后从头遍历数组,第一个正数的坐标+1即为所求。

        若,没有找到第一个正整数,则说明数组1-n连续,下一个最小正整数为n+1

        

        2.置换

        将nums中[1,n]的元素替换为对饮的坐标上

        遍历nums数组,其中第一个元素和坐标不对应的位置即为所求  

        while(nums[i]>0&&nums[i]<len&&nums[nums[i]-1]!=nums[i])

        额外的注意,当且仅当nums[nums[i]-1]==nums[i]时,while可能造成死循环。

1.解题【标记未出现的元素】

class Solution {
    public int firstMissingPositive(int[] nums) {
        int len=nums.length;
        //数组中没有1,则缺失的第一个正整数为1
        boolean flag=true;
        for(int i=0;i<len;i++){
            if(nums[i]==1) flag=false;
            //将负数和0置换为0,方便后续操作
            if(nums[i]<1||nums[i]>len) nums[i]=1;
        }
        if(flag) return 1;
        //若i位置上的数字出现过,则将对应位置置为负数
        for(int i=0;i<len;i++){
            nums[Math.abs(nums[i])-1]=-1*Math.abs(nums[Math.abs(nums[i])-1]);
        }
        
        //查找第一个为负的元素
        for(int i=0;i<len;i++){
            if(nums[i]>0) return i+1;
        }
        //如何没找到第一个正整数,则返回n+1
        return len+1;
    }
}

1.解题【置换】

class Solution {
    public int firstMissingPositive(int[] nums) {
        int len=nums.length;
        //将1-n之间的元素置换到对应坐标位置上
        for(int i=0;i<len;i++){
           while(nums[i]>0&&nums[i]<len&&nums[nums[i]-1]!=nums[i]){
            int temp=nums[i];
            System.out.println(i+" "+temp);
            nums[i]=nums[temp-1];
            nums[temp-1]=temp;
           }
        }
        //查找第一个为负的元素
        for(int i=0;i<len;i++){
            if(nums[i]!=i+1) return i+1;
        }
        //如何没找到第一个正整数,则返回n+1
        return len+1;
    }
}

2.复杂度分析

时间复杂度:O(n) 时间复杂度3个for循环的时间损耗

空间复杂度:O(1) 存储结果的空间损耗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值