由于每个人都希望软件的响应时间尽量短一些,所以软件公司都很重视软甲你的时间性能,都会在发布软件之前花不少精力进行时间效率优化。这也就不难理解为什么很多公司的面试官都把代码时间效率当做一个考查重点。面试官除了考查应聘者的编程能力,还关注应聘者有没有不断优化效率,追求完美的态度和能力。
首先,我们的编程习惯对代码的时间效率有很大的英雄,比如c/c++程序员要养成采用引或者指针传递复杂类型参数的习惯。如果采用值传递的方式,则从形参到实参会产生一次复制 操作。这样的复制是多余的操作,我们应该尽量避免。在举个列子,如果用C#做多次字符串的拼接操作,则不要用多次用String的+运算符来拼接字符串。因为这样会产生很多String的临时变量,造成时间和空间的浪费。更好的办法是用StringBuilder的Append方法来完成对字符串的拼接。如果我们平时不太注意这些英雄代码的效率的细节,没有养成良好的编码习惯,那么我们写出的代码可能会让面试官大失所望。
其次,即使同一个算法用循环和递归两种思路实现的时间效率可能会不大一样。递归的本质是吧一个大的复杂问题分解成两个或者多个小的简单问题。如果小问题中有相互叠加的部分,那么直接用递归实现虽然代码显得很简介,但是时间效率可能会非常差。对于这种类型的题目,我们可以用递归的思路来分析问题,但鞋代码的时候可以用数组来保存中间结果基于循环实现。绝大部分动态规划的算法的分析和代码实现都是分成这两个步骤完成的。
再次,代码的时间效率还能体现应聘者对数据结构和算法工地的掌握程度。同样是查找,如果是顺序查找则需要On的时间,如果输入的是排序的数组则需要Ologn的时间,如果事先已经构造好了哈希表,那么查找O1的时间内就能完成,我们只有对长剑的数据结构和算法都了然于胸,才能在需要的时候选择合适的数据结构和算法来解决问题。
看到这道题,很多应聘者就会想要是这个数组是排序的数组就好了,如果是排序好的数组,那么我们就能很容易统计出每个数字出现的次数。题目给出的数组没有说是排序号的,因此我们需要先给他排序,排序的时间复杂度是nlogn,最直观的算法通常不是面试官满意的算法,接下来我们试着找出更快的算法。
package question39_find_half;
/**
* @Classname Solution
* @Description TODO
* @Date 2020/3/28 14:03
* @Created by mmz
*/
public class Solution {
public int findHalf(int[] arr){
if(arr == null || arr.length<=0){
return 0;
}
int result = arr[0];
int count = 1;
for(int i = 1;i<arr.length;++i){
if(count == 0){
result = arr[i];
count++;
}else if(result == arr[i]){
count++;
}else{
count--;
}
}
if(count > 0 ){
int times = 0;
for(int i = 0 ;i<arr.length;++i){
if (arr[i] == result){
times++;
}
}
if(times * 2 >arr.length){
return result;
}
}
return 0;
}
}