最近公司来了两个面试者,在经过一番介绍与笔试以后,迎来了一个关于算法的问题。总体来说该题也不难,但是挺关注一个人的逻辑思维的。 说的是,给你一组数据,删掉其中一个保证剩下的几个数字的乘积达到最大化,如果是你你如何实现。 两个面试者都是脱口而出,我先遍历整个数组,由于数组是无序的,我通过冒泡法找到最小值并删除他的下标,剩下的数字的乘积足以成为最大的数据,面试结束后,我听面试他们的人说起此事,很明显,这两个人没有一个人会被录取,思维太过于简单化。 现在我来分析该题,一组数字,数字又会分为正数和负数,如果仅仅只是正数,很明显只需要遍历数组表就可以了,如果存在多个负数呢,或者说如果存在的数字全都是负数呢 。二话不说上图。
int []array1={-4,3, -5, -7, -21,9 , -1 ,5,6}; int index =findRemovedIndex(array1);例如如上所示,仅仅通过遍历将最小值-21删除,剩下的数字的乘积会是最大化吗,答案很明显 不会是最大化。
再看下面这个例子,如果改数组中存在0并且存在负数,又该如何。
int []array2={4,3,5, -7, -21,9, -1, -5,6,0}; index=findRemovedIndex(array2);通过遍历数组得到的最小值为-21,但是剩下的数字进行相乘确是得到的结果为0。并没有把乘积达到最大化,所以说,这两个面试者,死的不冤,想的太简单了,没有对多种情况有一个完美的定义。现在我来完成一下这道题。
由于数组中可能存在一个负数或者多个负数,首先我认为要进行一个字数的统计,统计该数组中负数的个数,并且要判断是奇数个还是偶数个。然后根据不同的情况才能来删除不同的数据,以达到删除合理的数字完成乘积最大化,废话不多说看代码!
// 1.统计负元素的个数 int negativeCount = 0; for ( int i = 0 ; i<array.length; i++) { if (array[i]<0){ negativeCount++; } } // 2.根据不同情况,选择要删除的元素 int tempIndex=0; if((negativeCount&1) ==1) { //情况A:负数个数是奇数 for(int i=1;i<array.length;i++) { if(array[i]<0){ if(array[tempIndex]>=0||array[i]>array[tempIndex]) { tempIndex=i; } } } return tempIndex; } else { //情况B:负数个数是偶数 if(array.length==negativeCount) { //子情况:所有元素都是负数 for(int i=1;i<array.length;i++) { if(array[i]<array[tempIndex]) { tempIndex=i; } } return tempIndex; } for(int i =1;i<array.length;i++) { if(array[i]>=0) { if(array[tempIndex]<0||array[i]<array[tempIndex]) { tempIndex =i; } } } return tempIndex; }只有当考虑到所有情况后,最终才能得出正确的结论,这道题看似不那么难,实则还是需要思考的,作为一个现代化的IT男还是要培养一下自己的思维能力。 如在下有所不足,欢迎交流!!