前几天,老吴给了我们一道算法题:

int[] arr= {1,92,56,58,57,3,70,71,74,72,73,75,18};

找出以上数组中连续数字最多的子数组。

简单地说,就是通过程序找到最多连续数字的那一串数组,这些数字可以不按照顺序排列,但是必须要连在一起。

用肉眼可以看出答案,就是70,71,74,72,73,75这一串数组,它满足连续且相邻。

那么,怎么找到它?

最简单粗暴的方法就是找出所有子数组,然后挨个匹配。

不过这样有点儿麻烦。

我想到了一种简单一些的方法。

既然我们的目标是找到连续且相邻的子数组,那么要满足连续,数组中的某个数必须有一个与它相邻的数在数组中。

那么我们可以对数组中每个数进行判断,看是否有它相邻的数字在数组中。

//判断是否有该数周围的数字
public static boolean findAround(int a,List<Integer> list) {
      if(list.contains(a-1)||list.contains(a+1)) {
        return true;
      }
    return false;
  }

然后再列一个新的数列,记录下判断结果,如果有子数组,则将该位记为1,如果没有,则记为0。

List<Integer> list =new ArrayList<>();
for(int b:arr) {
      if(findAround(b,listarr)) {
        list.add(1);
      }else {
        list.add(0);
      }
    }

那么得到的数组如下:

int[] arr= {0,0,1,1,1,0,1,1,1,1,1,1,0};

这样,为0的我们可以不用再进行判断,因为肯定不会连续,只需要将所有为1的标记的子数组取出,判断是否满足条件。

根据这个数组,我们可以对原数组进行截取,获得满足条件的两个子数组:56、58、57和70,71,74,72,73,75

//数组的截取

public static List<List<Integer>> substring(List<Integer> listindex,int[] array){
    List<List<Integer>> lists=new ArrayList<>();
    List<Integer> list = new ArrayList<>();
    for(int i=0;i<listindex.size();i++) {
      if(listindex.get(i)==0) {
        if(list.size()>0) {
          lists.add(list);
        }
        list = new ArrayList<>();
      }
      if(listindex.get(i)==1) {
        list.add(array[i]);
      }
    }
    return lists;
  }

最后将两个数组进行判断,如若最大值减去最小值+1等于数组的长度,那么就可以说明他们是连续的数组。

//判断是否连续
private static boolean isArrays(List<Integer> list1) {
    int max=0;
    int min=list1.get(0);
    for(Integer l :list1) {
      if(l>max) {
        max=l;
      }
      if(l<min) {
        min=l;
      }
    }
    if(max-min==list1.size()-1) {
      return true;
    }else {
      return false;
    }
  }

将数组及长度输出即可得到答案