array专题

581 Shortest Unsorted Continuous Subarray

问题:这道题目感概颇多,作为第一个array的简单题目就被缠住了。具体内容写在注释里面了。

217 Contains Duplicate

问题:这道题目可以看出有效的数字组合就是0,10,11三种组合。当遍历到某一位是0,下标加1;某一位是1,下标加2.如果到最后只剩下最后一位,并且是0,返回true。
学习:我用递归实现的,看了一个方法用循环实现了,代码简洁。

public boolean isOneBitCharacterV2(int[] bits) {
        int n = bits.length;
        int i = 0;
        while (i < n - 1) {
            if (bits[i] == 0)
                i++;
            else
                i += 2;
        }
        return i == n - 1;
    }

代码

118 Pascal’s Triangle

问题:利用杨辉三角形的性质
1 杨辉三角形以正整数构成,数字左右对称,每行由1主键变大,然后变小,变回1;
2 第n行,数字个数为n;
3 第n行,第k个数字为组合数 C(k1)(n1) C ( n − 1 ) ( k − 1 )
4 除每行最左侧与最右侧元素外,每个数字等于它的左上方与右上方数字之和。
代码

695 Max Area of Island

问题:计算小岛的最大面积,与 85 最大矩形面积的区别是:岛的面积只要连通就行,不一定要形成矩形。体现在深度优先搜索上不同。这道题目的精妙还在计算过就让grid[i][j] = 0,这样就不会重复计算了。这是我没有想到的。
代码

628 Maximum Product of Three Numbers

问题:题目的输入是一个整数数组,有正数,有负数。要求输出这些数组中任意三个数字乘积的最大值。
我的想法:最大乘积或者是三个最大正数的乘积,或者是两个具有最大绝对值的负数乘以最大的正数。那么我是不是可以按照数字的绝对值从大到小排序。然后找前三个数字相乘就可以。可以吗?不可以。因为是按照绝对值排序的,所以如果前三个数字恰好都是正数,那也罢了。如果其中一个,原来的数是负数,这个结果就不对了。
学习:思路的第一句是对的。只是处理方法不对。不应该按照数组元素的绝对值排序,这样之后再也找不到对应的原数字,会出问题。应该看到两个具有最大绝对值的负数就是整个数组中最小的两个数。如果能看到这个,就能找到解决方法了。

public int maximumProductV3(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        return Math.max(nums[0]*nums[1]*nums[n-1], nums[n-1]*nums[n-2]*nums[n-3]);
    }

学习2:最大乘积或者是三个最大正数的成绩,或者是两个具有最大绝对值的负数乘以最大的正数。对这句话可以再理解:找到最大的三个数max1,max2,max3,最小的两个数min1,min2。这应该一次循环就可以搞定,无需排序。有时候离成功就是那么近,目标设立对了,方法却错了。

public int maximumProductV2(int[] nums) {
        int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;
        int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
        for (int num : nums) {
            if (num > max1) {
                max3 = max2;
                max2 = max1;
                max1 = num;
            }else if(num > max2){
                max3 = max2;
                max2 = num;
            }else if(num > max3){
                max3 = num;
            }
            if (num < min1) {
                min2 = min1;
                min1 = num;
            }else if(num<min2){
                min2 = num;
            }
        }
        return Math.max(max1 * max2 * max3, min1 * min2 * max1);
    }

代码

414 Third Maximum Number

问题:题目简单,只要注意第三大数字=第三大不同的数字,注意去重。而且题目还给了一组最小的数字-2146473648.

 public int thirdMax(int[] nums) {
        int max1 = Integer.MIN_VALUE,max2=Integer.MIN_VALUE,max3=Integer.MIN_VALUE;
        int cnt = 0;
        boolean minvalue = true;
        for(int num:nums){
            if (num > max1) {
                max3 = max2;
                max2 = max1;
                max1 = num;
                cnt++;
            }else if(num > max2 && num!=max1){
                max3 = max2;
                max2 = num;
                cnt++;
            }else if(num > max3 && num!=max1 && num!=max2){
                max3 = num;
                cnt++;
            }else if(num==Integer.MIN_VALUE && minvalue){
                cnt++;
                minvalue = false;
            }
        }

        return cnt<3?max1:max3;
    }

643 Maximum Average Subarray I

问题:要找到长度为k的平均值最大的子数组的平均值。只要找到符合条件的子数组即可。题目可以先用for循环,指定子数组的起始位置、结束位置计算;然后会发现超时,为了减少重复的加和步骤,使用滑动窗口的方式。这种窗口滑动的方式在nlp的算法和深度学习中都有使用。

public double findMaxAverageV3(int[] nums, int k) {
        int n = nums.length;
        int sum = 0;
        for (int i = 0; i < k; i++) {
            sum += nums[i];
        }
        int maxSum = sum;
        for (int i = k; i < n; i++) {
            sum += nums[i] - nums[i - k];
            maxSum = Math.max(maxSum, sum);
        }
        return (maxSum+0.0)/k;
    }

448 Find All Numbers Disappeared in an Array

问题:题目简单。输入一个数组,数组元素是[1,n],n是数组长度。有些元素可能重复,有些元素可能没出现。返回没有出现的元素。要求不用额外的空间,用O(n)时间复杂度完成。
我的思路:先使用一个新数组data,长度为n+1。遍历入参nums,设置data[nums[i]]=1。最后遍历data[i]=1就表示i出现过,否则就没有出现。所以关键是标记出出现的元素。可以用数组下标和出现的元素关联起来。如果没有新数组data,那就在原数组nums上做修改。修改的方式有很多种,例如设置为0,设置为负数,原数组值+n等等。我自己实现的修改数组值为0,方式不够漂亮,参考了原数组值+n的方式。
代码

724 Find Pivot Index

问题:从左向右一次选择pivot的index 当选择pivot index 为i的时候leftsum=sum(0,i-1),rightsum=sum(i+1,n-1) ;当选择pinot index 为(i+1)的时候,leftsum=sum(0,i)=sum(0,i-1)+a[i] rigtsum=sum(i+2,n-1)=sum(i+1,n-1)-a[i+1]。注意:左边可以是0个元素,右边也可以是0个元素
学习:更加简洁版本。leftsum + rightsum + nums[i] = sum,所以leftsum和rightsum只要计算一个就可以。只是没有想明白为什么这个版本更慢了。(pivotIndexV2)
代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值