数组------最短排序+左右最值最大差+局部最小值位置+子数组最大乘积+多数组中位数



最短排序

对于一个无序数组A,请设计一个算法,求出需要排序的最短子数组的长度。

给定一个整数数组A及它的大小n,请返回最短子数组的长度。

测试样例:
[1,5,3,4,2,6,7],7
返回:4
(1)
import java.util.*;
public class ShortSubsequence {
    public int findShortest( int [] A, int n) {
         if (A== null ||n<= 1 ){
             return 0 ;
         }
        int indexMin= 0 ;
        int indexMax=n- 1 ;
        int i= 0 ,j=n- 1 ;
        while (i!=n- 1 &&A[++i]>=A[indexMin++]);
        if (i==n- 1 ) return 0 ;
        while (A[--j]<=A[indexMax--]);
        int max=A[j],min=A[i];
        for ( int k=i- 1 ;k<=j+ 1 ;k++){
            max=Math.max(A[k],max);
            min=Math.min(A[k],min);
        }
        i= 0 ;j=n- 1 ;
        while (A[i++]<=min);
        while (A[j--]>=max);
        return j-i+ 3 ;
      }
}


(2)

import java.util.*;

public class ShortSubsequence {
    public int findShortest(int[] A, int n) {
        if(A==null||n<=1) return 0;
        int max=A[0];
        int min=A[n-1];
        int maxIndex=0;
        int minIndex=n-1;
        for(int i=1;i<n;i++){
           if(A[i]<A[i-1]){
               max=Math.max(max,A[i-1]);
               maxIndex=i;
           }
            else{
                if(A[i]<max) maxIndex=i;
            }
        }
        if(maxIndex==0)return 0;
        for(int i=n-2;i>=0;i--){
           if(A[i]>A[i+1]){
               min=Math.min(min,A[i+1]);
               minIndex=i;
           }
            else{
                if(A[i]>min) minIndex=i;
            }
        }
        return maxIndex-minIndex+1;
    }
}

(3)

import java.util.*;
public class ShortSubsequence {
     public int findShortest( int [] A, int n) {
         if (A== null ||n<= 1 ) return 0 ;
         int max=A[ 0 ];
         int min=A[n- 1 ];
         int maxIndex= 0 ;
         int minIndex=n- 1 ;
         for ( int i= 1 ;i<n;i++){
            if (A[i]<max){
                maxIndex=i;
            }
             else {
                 max=Math.max(max,A[i]);
             }
         }
         if (maxIndex== 0 ) return 0 ;
         for ( int i=n- 2 ;i>= 0 ;i--){
            if (A[i]>min){
                minIndex=i;
            }
             else {
                 min=Math.min(min,A[i]);
             }
         }
         return maxIndex-minIndex+ 1 ;
     }
}



左右最值最大差

给定一个长度为N(N>1)的整型数组A,可以将A划分成左右两个部分,左部分A[0..K],右部分A[K+1..N-1],K可以取值的范围是[0,N-2]。求这么多划分方案中,左部分中的最大值减去右部分最大值的绝对值,最大是多少?

给定整数数组A和数组的大小n,请返回题目所求的答案。

测试样例:
[2,7,3,1,1],5
返回:6
(1)
import java.util.*;
public class MaxGap {
     public int findMaxGap( int [] A, int n) {
         if (A== null ||n<= 1 ){
             return 0 ;
         }
         int result;
         int [] leftMax= new int [n];
         int [] rightMax= new int [n];
         leftMax[ 0 ]=A[ 0 ];
         rightMax[n- 1 ]=A[n- 1 ];
         for ( int i= 1 ;i<n;i++){
             leftMax[i]=Math.max(A[i],leftMax[i- 1 ]);
             rightMax[n- 1 -i]=Math.max(A[n- 1 -i],rightMax[n-i]);
         }
         result=Math.abs(leftMax[ 0 ]-rightMax[ 1 ]);
         for ( int i= 1 ;i<n- 1 ;i++){
             result=Math.max(result,Math.abs(leftMax[i]-rightMax[i+ 1 ]));
         }
         return result;
     }
}
(2)
import java.util.*;
public class MaxGap {
     public int findMaxGap( int [] A, int n) {
         if (A== null ||n<= 1 ) return 0 ;
         int max=Integer.MIN_VALUE;
         for ( int i= 0 ;i<n;i++) max=Math.max(A[i],max);
         return max-Math.min(A[ 0 ],A[n- 1 ]);
     }
}


局部最小值位置
定义局部最小的概念。arr长度为1时,arr[0]是局部最小。arr的长度为N(N>1)时,如果arr[0]<arr[1],那么arr[0]是局部最小;如果arr[N-1]<arr[N-2],那么arr[N-1]是局部最小;如果0<i<N-1,既有arr[i]<arr[i-1]又有arr[i]<arr[i+1],那么arr[i]是局部最小。 给定无序数组arr,已知arr中任意两个相邻的数都不相等,写一个函数,只需返回arr中任意一个局部最小出现的位置即可。
public class Solution {
     public int getLessIndex( int [] arr) {
         if (arr== null ||arr.length<= 0 ) return - 1 ;
         if (arr.length== 1 ||arr[ 0 ]<arr[ 1 ]) return 0 ;
         if (arr[arr.length- 1 ]<arr[arr.length- 2 ]) return arr.length- 1 ;
         int len=arr.length;
         int left= 1 ,right=len- 2 ,mid= 0 ;
         while (left<right){
             mid=(left+right)/ 2 ;
             if (arr[mid]>arr[mid- 1 ])  right=mid- 1 ;
             else if (arr[mid]>arr[mid+ 1 ]) left=mid+ 1 ;
             else return mid;
         }
         return left;
     }
}



子数组最大乘积
给定一个double类型的数组arr,其中的元素可正可负可0,返回子数组累乘的最大乘积。例如arr=[-2.5,4,0,3,0.5,8,-1],子数组[3,0.5,8]累乘可以获得最大的乘积12,所以返回12。

public class Solution {
     public double maxProduct( double [] arr) {
         if (arr== null ||arr.length== 0 ) return 0 ;
         int len=arr.length;
         double result,max,min,maxProduct,minProduct;
         result=maxProduct=minProduct=arr[ 0 ];
         for ( int i= 1 ;i<len;i++){
             max=maxProduct*arr[i];
             min=minProduct*arr[i];
             maxProduct=Math.max(Math.max(max,min),arr[i]);
             minProduct=Math.min(Math.min(max,min),arr[i]);
             result=Math.max(result,maxProduct);
         }
         return result;
     }
}
连续子数组的最大和

题目描述

HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?

public class Solution {
     public int FindGreatestSumOfSubArray( int [] array) {
         if (array== null ||array.length== 0 ){
            return 0 ;
         }
         int result=array[ 0 ];
         int max=array[ 0 ];
         for ( int i= 1 ;i<array.length;i++){
             max=Math.max(max+array[i],array[i]);
             result=Math.max(result,max);
         }
         return result;
     }
}


多数组中位数
给定两个有序数组arr1和arr2,两个数组长度都为N,求两个数组中所有数的上中位数。
例如:
arr1 = {1,2,3,4};
arr2 = {3,4,5,6};
一共8个数则上中位数是第4个数,所以返回3。

arr1 = {0,1,2};
arr2 = {3,4,5};
一共6个数则上中位数是第3个数,所以返回2。

要求:时间复杂度O(logN)
public class Solution {
     public int getUpMedian( int [] arr1, int [] arr2) {
         if (arr1== null ||arr2== null ||arr1.length!=arr2.length||arr1.length== 0 ) throw new RuntimeException( "Your data is invalid!" );;
         return upMedian(arr1, 0 ,arr1.length- 1 ,arr2, 0 ,arr2.length- 1 );
     }
     public int upMedian( int [] arr1, int start1, int end1, int [] arr2, int start2, int end2){
         if (start1==end1) return Math.min(arr1[start1],arr2[start2]);
         int mid1=(start1+end1)/ 2 ,mid2=(start2+end2)/ 2 ;
         int flag=(end1-start1+ 1 )& 1 ^ 1 ;
         if (arr1[mid1]>arr2[mid2]){
             return upMedian(arr1,start1,mid1,arr2,mid2+flag,end2);
         }
         else {
             return upMedian(arr1,mid1+flag,end1,arr2,start2,mid2);
         }
     }
}






多数组K大数
给定两个有序数组arr1和arr2,在给定一个整数k,返回两个数组的所有数中第K小的数。
例如:
arr1 = {1,2,3,4,5};
arr2 = {3,4,5};
K = 1;
因为1为所有数中最小的,所以返回1;

arr1 = {1,2,3};
arr2 = {3,4,5,6};
K = 4;
因为3为所有数中第4小的数,所以返回3;

要求:如果arr1的长度为N,arr2的长度为M,时间复杂度请达到O(log(min{M,N}))。
public class Solution {
     public int findKthNum( int [] arr1, int [] arr2, int kth) {
         if (arr1== null ||arr2== null ||kth< 1 ||arr1.length+arr2.length<kth) {
             throw new RuntimeException( "Your data is invalid!" );
         }
         int len1=arr1.length,len2=arr2.length;
         int [] longarr=arr1,shortarr=arr2;
         int longlen=len1,shortlen=len2;
         if (len1<len2) {
             longarr=arr2;
             shortarr=arr1;
             longlen=len2;
             shortlen=len1;
         }
         if (kth<=shortlen){
             return upMedian(longarr, 0 ,kth- 1 ,shortarr, 0 ,kth- 1 );
         }
         if (shortlen<kth&&kth<longlen){
             if (longarr[kth-shortlen- 1 ]>=shortarr[shortlen- 1 ]){
                 return longarr[kth-shortlen- 1 ];
             }
             return upMedian(longarr,kth-shortlen,kth- 1 ,shortarr, 0 ,shortlen- 1 );
         }
         else {
             if (longarr[kth-shortlen- 1 ]>shortarr[shortlen- 1 ]){
                 return longarr[kth-shortlen- 1 ];
             }
             if (kth-longlen- 1 >= 0 &&shortarr[kth-longlen- 1 ]>longarr[longlen- 1 ]){
                 return shortarr[kth-longlen- 1 ];
             }
             return upMedian(longarr,kth-shortlen,longlen- 1 ,shortarr,kth-longlen,shortlen- 1 );
         }
         
     }
     public int upMedian( int [] arr1, int start1, int end1, int [] arr2, int start2, int end2){
         if (start1==end1) {
             return Math.min(arr1[start1],arr2[start2]);
         }
         int mid1=(start1+end1)/ 2 ,mid2=(start2+end2)/ 2 ;
         int flag=(end1-start1+ 1 )& 1 ^ 1 ;
         if (arr1[mid1]>arr2[mid2]){
             return upMedian(arr1,start1,mid1,arr2,mid2+flag,end2);
         }
         else {
             return upMedian(arr1,mid1+flag,end1,arr2,start2,mid2);
         }
     }
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值