数组相关

1.一个无序有正有负数组,求乘积最大的三个数的乘积

结果只可能是最大的三个正数的乘积,或者两个最小的负数乘最大的正数

所以就是遍历一遍求最大的三个数和最小的两个数

public int maximumProduct(int[] nums) {
        int max1 = Integer.MIN_VALUE;
        int max2 = Integer.MIN_VALUE;
        int max3 = Integer.MIN_VALUE;
        int min1 = Integer.MAX_VALUE;
        int min2 = Integer.MAX_VALUE;
        int len = nums.length;
        for(int i=0;i<len;i++){
            if(nums[i] > max1){
                max3 = max2;
                max2 = max1;
                max1 = nums[i];
            }else if(nums[i] > max2){
                max3 = max2;
                max2 = nums[i];
            }else if(nums[i] > max3){
                max3 = nums[i];
            }
            
            if(nums[i] < min1){
                min2 = min1;
                min1 = nums[i];
            }else if(nums[i] < min2){
                min2 = nums[i];
            }
        }
        int max = max1*max2*max3;
        int min = max1*min1*min2;
        return max>min?max:min;
    }

2.判断某个数组分成n段,每段的和相同

这里是三段

就是遍历一遍找出那个除之后的值,然后遍历一遍

public boolean isEqual_3(int[] a) {
        int n=a.length;
        int sum=0;
        for(int i=0;i<n;i++) sum+=a[i];
        
        if(sum%3!=0) return false;
        int help=sum/3;
        int temp=0;
        int item=0;
        int i;
        for(i=0;i<n;i++) {
            temp+=a[i];
            if(temp==help) {
                item++;
                temp=0;
            }
            
        }
        if(item==3&&i==n) return true;
        else return false;
    }

 3.和至少为K 的最短子数组的长度

A = [2,-1,2], K = 3 输出3

首先计算前缀数组,根据前缀数组来计算

public int shortestSubarray(int[] A, int K) {
        int n = A.length;
        int minLen = n + 1;
        int[] preSum = new int[n+1];
        preSum[0] = 0;
        for (int i = 0; i < n; i++) {
            preSum[i+1] = preSum[i] + A[i];
        }
        Deque<Integer> q = new LinkedList<>();
        for (int i = 0; i < n + 1; i++) {
            while (!q.isEmpty() && preSum[i] <= preSum[q.getLast()]) {
                q.pollLast();
            }

            while (!q.isEmpty() && preSum[i] - preSum[q.getFirst()] >= K) {
                int curLen = i - q.pollFirst();
                minLen = Math.min(minLen, curLen);
            }
            q.addLast(i);
        }
        return minLen == n + 1 ? -1 : minLen;
    }

 4.求最大连续子数组的和

public int maxSubArray(int[] nums) {
        int len = nums.length;
           if(len == 0){
               return 0;
           }
           int sum = nums[0]; //sum表示前i-1个数组元素的最大连续子数组的和
           int sum1 = nums[0];//sum1表示当前以a[i-1]为结束元素的连续子数组的和
           int start=0,end=0;
           for(int i=1;i<len;i++){
               if(sum1>0){//sum1>0则a[i]成为sum1中最后一个元素
                   sum1 = sum1+nums[i];
                   end=i;
               }else{//否则,a[i]成为sum1中唯一的元素
                   sum1= nums[i];
                   start=i;
               }
               if(sum < sum1){
                   sum = sum1;
               }
           }
           System.out.println(start+"--"+end);
       return sum;
    }

5.求最大子矩阵的和,利用上面一维子数组求和的思想

static int maxMatrxSum(int[][] a) {
        int n=a.length;
        int m=a[0].length;
        int[][] dp=new int[n][m];
        dp[0][0]=a[0][0];
        int res=-1;
        for(int i=0;i<n;i++) {
           int[] arr=new int[m];
           for(int j=i;j<n;j++) {//第i行开始到第j行
               for(int k=0;k<m;k++) {
                   arr[k]+=a[j][k];
               }
               res=Math.max(res, maxArrSum(arr));
           }
        }
        return res;
    }
    public static int maxArrSum(int arr[])
    {
        int max=0,sum=0;
        for(int i=0;i<arr.length;i++)
        {
            if(sum<=0)
            {
                sum=arr[i];
            }
            else {
                sum+=arr[i];
            }
            max=Math.max(sum, max);
        }
        return max;
    }

 

posted @ 2019-09-03 11:12  LeeJuly  阅读(113)  评论(0)    收藏  举报