238.除自身以外数组的乘积

image-20200606110139628

哈希表+除法(违规)

思路

  • 第一次遍历用哈希表记录数组出现 0的下标 ,同时计算非零元素的乘积。
  • 第二次遍历数组,对数组元素为0的个数进行分类讨论,详细见代码
  • 最致命的地方是 用到了除法

代码

/*
 *2ms O(n)
 */
public  int[] productExceptSelf2(int[] nums){
        int len=nums.length;
        int[] ans=new int[len];
        Map<Integer,Integer> map=new HashMap<>();
        int tmp=1;
        for(int i=0;i<len;i++){
            if(nums[i]==0){
                map.put(i, 1);
                continue;
            }
            tmp*=nums[i];
        }
        for(int i=0;i<len;i++){
            //数组不包含零
            if(map.size()==0){
                ans[i]=tmp/nums[i];
            }else{//数组包含零
                if(map.size()==1){//只有一个零
 //                   ans[i]=map.containsKey(i)?0:tmp;   合并
                    if(!map.containsKey(i)){
                        ans[i]=0;
                    }else{
                        ans[i]=tmp;
                    }
                }else{//多个零
                    ans[i]=0;
                }
//                ans[i]=map.size()==1?(map.containsKey(i)?0:tmp):0;  合并
            }
        }
        return ans;
    }

优化

//if else太多 合并
public int[] productExceptSelf(int[] nums) {
       int len=nums.length;
        int[] ans=new int[len];
        Map<Integer,Integer> map=new HashMap<>();
        int tmp=1;
        for(int i=0;i<len;i++){
            if(nums[i]==0){
                map.put(i, 1);
                continue;
            }
            tmp*=nums[i];
        }
        for(int i=0;i<len;i++){
            ans[i]=map.size()==0?(tmp/nums[i]):(map.size()==1?(!map.containsKey(i)?0:tmp):0);
        }
        return ans;
    }

优解

思路

  • 乘积=当前数左边的乘积 * 当前数右边的乘积
//1ms
public static int[] productExceptSelf3(int[] nums){
    int[] res=new int[nums.length];
    int k=1;//理解为最左端元素的左乘积
    //计算并保存各元素的左乘积
    for(int i=0;i<res.length;i++){
        res[i]=k;
        k*=nums[i];
    }
    
    //计算并保存各元素的右乘积,在左乘积的基础上拼接(乘)右乘积
    k=1;//可以理解为最右端元素的右乘积
    for(int i=res.length-1;i>=0;i--){
        res[i]*=k;
        k*=nums[i];
    }
    return res;
}

参考链接

罗梁:乘积=当前数左边的乘积 * 当前数右边的乘积

posted @ 2020-06-06 11:27  YH_Simon  阅读(161)  评论(0编辑  收藏  举报