这个题目是腾讯电话面试的考题之一:给定一个数组,不适用任何排序方法,快排什么的,判断出一个数列是否是等差数列,并且要求算法复杂度不得超过快排。
我的想法是只是判断一个数组是否为等差数列,相对来说容易好多。思路如下:
(1)对数组进行第一次遍历,找出数组中的min.max
(2)如果是等差数列,那么公差必然是(max-min)/(n-1) n为元素个数
(3)有了公差,有了首项,有了尾项。这个等差数列实际上就模拟出来了。接下来就是判断是不是符合要求
最后出来的程序,只是对数组做了两次遍历。时间复杂度为线性的,比快排(nlogn)少好多,尤其n相当大时。如果大家有其他的想法,可以交流一下,共同进步。同时,如果有什么不对的地方,批评指正。
package perceptron;
import java.io.IOException;
import java.util.TreeMap;
public class arithmetic {
public static void main(String[] args) throws IOException{
double[] seq = {2,4,6,10};
judgeSeq(seq);
}
public static void judgeSeq(double[] seq){
double min = Double.MAX_VALUE;
double max = Double.MIN_VALUE;
for(int i=0;i<seq.length;i++){//对数组进行第一次遍历,找出数组中min ,max
if(seq[i]<min){
min = seq[i];
}
else if(seq[i]>max){
max = seq[i];
}
}
double Dif = (max-min)/(seq.length-1); //求得公差
String flag = "True";
if(Dif==0){ //如果公差为0,那么说明数列中所有的数都是相同的 ,判断所有数是否相同
for(int i=0;i<seq.length;i++){
if(seq[i]!=min){
flag = "false";
break;
}
}
}
else{//公差不为0
TreeMap<Double,Integer> tm = new TreeMap<Double,Integer>();//建立容器,存储每个数字出现的次数
for(int i=0;i<seq.length;i++){
//统计每个谁出现的次数,因为公差不为0,必然不可能出现相同的数字
if(tm.get(seq[i])==null){
tm.put(seq[i], 0);
}
tm.put(seq[i],tm.get(seq[i])+1);
if(tm.get(seq[i])>1){
flag = "false";
break;
}
double DifNum = (seq[i]-min)/Dif; // 判断(seq[i]-min)/Dif是否为整数,在[0,seq.length-1]之间
int s = (int)DifNum;
if(DifNum-(double)s!=0||DifNum>seq.length||DifNum<0){
flag = "false";
break;
}
}
}
if(flag.equals("True")){
System.out.println("属于等差数列");
}
else{
System.out.println("不属于等差数列");
}
}
}