阿里实习在线编程测试--数组四等分

15 篇文章 0 订阅

/** 请完成下面这个函数,实现题目要求的功能 **//** 当然,你也可以不按照这个模板来作答,完全按照自己的想法来 ^-^ **//** * * 对于一个长度为N的整型数组A, 数组里所有的数都是正整数,对于两个满足0<=X <= Y <N的整数,A[X], A[X+1] … A[Y]构成A的一个切片,记作(X, Y)。 用三个下标 m1, m2, m3下标满足条件 0 < m1, m1 + 1 < m2, m2 +1 < m3 < N – 1。 可以把这个整型数组分成(0, m1-1), (m1+1, m2-1), (m2+1, m3-1), (m3+1, N-1) 四个切片。如果这四个切片中的整数求和相等,称作“四等分”。 编写一个函数,求一个给定的整型数组是否可以四等分,如果可以,返回一个布尔类型的true,如果不可以返回一个布尔类型的false。 限制条件: 数组A最多有1,000,000项,数组中的整数取值范围介于-1,000,000到1,000,000之间。 要求: 函数的计算复杂度为O(N),使用的额外存储空间(除了输入的数组之外)最多为O(N)。 例子: 对于数组A=[2, 5, 1, 1, 1, 1, 4, 1, 7, 3, 7] 存在下标 2, 7, 9使得数组分成四个分片[2, 5], [1, 1, 1, 4], [7], [7],这三个分片内整数之和相等,所以对于这个数组,函数应该返回true。 对于数组 A=[10, 2, 11, 13, 1, 1, 1, 1, 1], 找不到能把数组四等分的下标,所以函数应该返回false。 *//****************************************************/

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2.   
  3. public class Solution {  
  4.   
  5.     /** 
  6.      * 注意: 
  7.      * 1、只删除3个元素,等分为四份。 
  8.      * 2、数组元素为正整数。 
  9.      * 3、疑问:后面又说整数取值范围介于-1,000,000到1,000,000之间?明显混淆视听,看来阿里的题考查阅读与观察啊! 
  10.      * 方法一: 
  11.      * 1、先二等分,去除中间那个元素。至少中间左边还是右边有待考证 
  12.      *此方法有bug 
  13.      * 
  14.      * */  
  15.     /** 
  16.      * indexBegin开始索引,indexEnd结束索引。 
  17.      * 在sumArr,与chooseRemove中均计算的是indexBegin<=i<indexEnd的元素。 
  18.      * 元素分布:0至v1-1,v1+1到v2-1,v2+1到N-1 
  19.      * */  
  20.     /**测试用例: 
  21.      * {1,1,1,1,7,1,3,4,1,2,1,5,2,2} true;把7换成10,把4换成1,原式也可等分,但却如下 
  22.      * {1,1,1,1,10,1,3,1,1,2,1,5,2,2} false; 
  23.      * {2,2,5,1,2,1,1,3,1,10,1,1,1,1} false;上面的倒序。看来与顺序无关,算法还是存在问题,此种解法存在问题。 
  24.      * 
  25.      * */  
  26.     //方法二**********************************************  
  27.     /** 
  28.      * 从两边开始找,找到之后再找中间 
  29.      * 技巧,注意到只删除3个元素,又因为要第一分组与第四分组相等. 
  30.      * 设等分值为v,第一分组n1与第二分组元素n4个数共为n,则2<=N-3-n<=2v; 
  31.      * 此方问题,能够解决方法一的问题*/  
  32.     static boolean resolve2(int[] A) {  
  33.         int[] re=findValLocate(A);  
  34.         System.out.println("寻找完毕,开始检查: "+Arrays.toString(re));  
  35.         re[2]=checkingFind(A,re[0],re[1]+1,re[3]-1); //减1是由于有4部分,最后一部分至少占用1个位置。  
  36.         System.out.println("检查: "+Arrays.toString(re));  
  37.         int v3=checkingFind(A,re[0],re[2]+1,re[3]);//检查第四部分,的分割点是否为re[3]  
  38.         if(v3==re[3]){  
  39.             return true;  
  40.         }  
  41.         return false;  
  42.     }  
  43.     static int checkingFind(int[] A ,int val,int begin,int end){  
  44.         int s=0;  
  45.         for(int i=begin;i<end;++i){  
  46.             s=s+A[i];  
  47.             if(s==val){  
  48.                 //返回要去除那个点。  
  49.                 return i+1;  
  50.             }  
  51.         }  
  52.         return -1;  
  53.     }  
  54.     /*返回均分值,与要去除的第一个和第三个位置*/  
  55.     static int[] findValLocate(int[] A){  
  56.         int v1=0,v4=0;  
  57.         for(int i=0,j=A.length-1;i<j;){  
  58.   
  59.             if(v1<v4){  
  60.                 v1=v1+A[i];  
  61.                 ++i;  
  62.             }else if(v1>v4){  
  63.                 v4=v4+A[j];  
  64.                 --j;  
  65.             }else{  
  66.                 /*验证:2<=N-3-n<=2v*/  
  67.                 int m=A.length-3-(i+1+A.length-j);  
  68.                 if(m>=2 && m<=2*v1 ){  
  69.                     /*这里返回的是去除点的位置,i,j没有加减, 
  70.                     是因为以前的操作都让它向后移了一位了, 
  71.                     现在指的就是要去除的点*/  
  72.                     int re[]={v1,i,0,j};  
  73.                     return re;  
  74.                 }else{  
  75.                     v1=v1+A[i];  
  76.                     ++i;  
  77.                 }  
  78.   
  79.             }  
  80.         }  
  81.         return null;  
  82.     }  
  83.     //方法二结束**********************************************  
  84.     //方法一(此方有问题)**********************************************  
  85.     static boolean resolve(int[] A) {  
  86.         int v2=chooseRemove(A,0,A.length-1);  
  87.         int v1=chooseRemove(A,0,v2-1);  
  88.         int v3=chooseRemove(A,v2+1,A.length-1);  
  89.         int s1=sumArr(A,0,v1-1);  
  90.         int s2=sumArr(A,v1+1,v2-1);  
  91.         int s3=sumArr(A,v2+1,v3-1);  
  92.         int s4=sumArr(A,v3+1,A.length-1);  
  93.   
  94.         System.out.println("去除的元素依次是:A["+v1+"]="+A[v1]+" ; "  
  95.                                             +"A["+v2+"]="+A[v2]+" ; "  
  96.                                             +"A["+v3+"]="+A[v3]+" ; ");  
  97.         System.out.println("四个部分和是:"+"s1="+s1+" ; "  
  98.                                             +"s2="+s2+" ; "  
  99.                                             +"s3="+s3+" ; "  
  100.                                             +"s4="+s4+" ; ");  
  101.         if(s1==s2&&s3==s4&&s2==s3){  
  102.             return true;  
  103.         }  
  104.   
  105.     return false;  
  106.   
  107.     }  
  108.     static int sumArr(int[] A, int indexBegin, int indexEnd){  
  109.         int sum=0;  
  110.         for(int i=indexBegin; i<=indexEnd;++i){  
  111.             sum =sum +A[i];  
  112.         }  
  113.         return sum;  
  114.     }  
  115.     static int chooseRemove(int[] A, int indexBegin, int indexEnd){  
  116.         int ave=sumArr(A,indexBegin,indexEnd)/2;  
  117.         int val=0;  
  118.         for(int i=indexBegin;i<=indexEnd;++i){  
  119.             val=val+A[i];  
  120.             if(val>ave){  
  121.                 return i;  
  122.             }  
  123.         }  
  124.         return -1;  
  125.     }  
  126.     //方法一结束**********************************************  
  127.   
  128.     public static void main(String[] args){  
  129.         /*ArrayList<Integer> inputs = new ArrayList<Integer>(); 
  130.         Scanner in = new Scanner(System.in); 
  131.         String line = in.nextLine(); 
  132.         while(line != null && !line.isEmpty()) { 
  133.             int value = Integer.parseInt(line.trim()); 
  134.             if(value == 0) break; 
  135.             inputs.add(value); 
  136.             line = in.nextLine(); 
  137.         } 
  138.         int[] A = new int[inputs.size()]; 
  139.         for(int i=0; i<inputs.size(); i++) { 
  140.             A[i] = inputs.get(i).intValue(); 
  141.         }*/  
  142.         //int[] A={1,1,1,1,7,1,3,4,1,2,1,5,2,2};  
  143.         int[] A={1,1,1,1,10,1,3,1,1,2,1,5,2,2};  
  144.         Boolean res = resolve2(A);  
  145.   
  146.         System.out.println(String.valueOf(res));  
  147.     }  
  148. }  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值