阿里巴巴集团2017暑期实习Java研发工程师在线编程题-数组分片

来源:互联网 发布:小型数据库管理系统 编辑:程序博客网 时间:2024/04/29 19:55

题目:一个整型(非负)数组,将其划分为总和相同的4个切片,例如:{2,5,1,1,1,1,4,1,7,3,7},切片操作后划分为:{2,5},{1,1,1,4},{7},{7},也就找到所谓的四等分点,切分点分别是1,1,3,切分点不算在总和内。输出能否分片。要求时间复杂度和空间复杂度为o(n)。


思路:

  1. 两个Map,一个存<总和,位置>,一个存<位置,总和>。
  2. 由于数组非负,先由头尾指针向中间逼近,先将数组分成三段< L,M,R >,如果左边大则左移尾指针,如果右边大则右移头指针,最后使得左右部分相等,大小记为A
  3. 然后处理中间部分M,看其能否分成两部分< LM,LR >,使得他们的总和都等于A。方法是从<总和,位置>的Map中找总和为2A的位置i,即满足LM==L,如果这个位置i存在并且在左右指针之间,根据尾指针和i以及Map<位置,总和>算出LR的和,判断是否等于A,如果相等,则输出true

{2,5,1,1,1,1,4,1,7,3,7}
       ↑            ↑    ↑
   头指针        i  尾指针

以下代码通过了在线编程的所有测试用例:

public class FourPiece {    public static void main(String[] args){//        int[] nums = {2,5,4,7,2,5,4,7,2,5,4,7,2,5,4,7,2,5,4,7,2,5,4,7};//        int[] nums = {1,2,1,3,1,4,2};        int[] nums = {2,5,1,1,1,1,4,1,7,3,7};//        int[] nums = {10,2,11,13,1,1,5,1,1,1,10,2,11,12,5,1,1,1,1,1,10,2,11,10,5,1,1,1,1,34};        System.out.print(canDevide(nums));    }    public static boolean canDevide(int[] nums){        if(nums == null || nums.length < 7){            return false;        }        HashMap<Long,Integer> indexMap = new HashMap<Long,Integer>();//<总和,位置>        HashMap<Integer,Long> sumMap = new HashMap<Integer,Long>();//<位置,总和>        long curSum = 0;        for(int i = 0; i < nums.length; i++){            indexMap.put(curSum,i);            sumMap.put(i,curSum);            curSum += nums[i];        }        long leftSum = nums[0];//最左段总和        long rightSum = nums[nums.length - 1];//最右段总和        int leftIndex = 1;//左分割点        int rightIndex = nums.length - 2;//右分割点        while(leftIndex + 3 < rightIndex){            if(leftSum == rightSum){                if(indexMap.get((leftSum << 1) + nums[leftIndex]) != null){                    int middleIndex = indexMap.get((leftSum << 1) + nums[leftIndex]);//中间分割点                    if(middleIndex > leftIndex + 1 && middleIndex < rightIndex - 1){                        if(sumMap.get(rightIndex) - sumMap.get(middleIndex + 1) == leftSum){                            return true;                        }                    }                }                leftSum += nums[leftIndex++];                rightSum += nums[rightIndex--];            }            else{                if(leftSum < rightSum){                    leftSum += nums[leftIndex++];                }                else{                    rightSum += nums[rightIndex--];                }            }        }        return false;    }}
0 0
原创粉丝点击