最长等差数列
问题:
给定一个未排序数组,找出其中最长的等差数列(无需保证数字顺序)。
分析:
该问也属于动态规划问题范畴,因为当前问题依赖子问题。
(1)首先对数组进行升序排序,数组自然构成不同的等差数列。
(2)子问题结果记录。使用map记录一对多结果。因为相同的公差d对应着不同的数列。我选择的数据结构为嵌套Map。
Arrays.sort(dp);
/*
key1:等差值
map-key2:数列结尾值
map-value2:长度
*/
Map<Integer,Map<Integer,Integer>> maps = new HashMap<>();
(3)特殊情况:
1、公差为0:在内循环内只记录一次,我使用的是标志位。导致这样的原因是我选择的数据结构。
2、相同公差:如12223,只有当以3为key的map不存在时才记录。保证了不错误记录。
代码:
1 import java.util.*; 2 3 public class Main{ 4 public static void main(String args[]){ 5 Scanner in = new Scanner(System.in); 6 int n = in.nextInt(); 7 int[] dp = new int[n]; 8 for(int i=0;i<n;i++){ 9 dp[i] = in.nextInt(); 10 } 11 Arrays.sort(dp); 12 /* 13 key1:等差值 14 map-key2:数列结尾值 15 map-value2:长度 16 */ 17 Map<Integer,Map<Integer,Integer>> maps = new HashMap<>(); 18 19 20 for(int i=1;i<n;i++){ 21 int count=0; 22 for(int j=i-1;j>=0;j--){ 23 int diff = dp[i]-dp[j]; 24 25 if(maps.containsKey(diff)){ 26 Map<Integer,Integer> tmap = maps.get(diff); 27 //不计算重复值 28 if( diff!=0 && !tmap.containsKey(dp[i]) && tmap.containsKey(dp[j])){ 29 Map<Integer,Integer> t = new HashMap<>(); 30 t.put(dp[i],tmap.get(dp[j])+1); 31 maps.put(diff,t); 32 }else if(diff==0 && tmap.containsKey(dp[i]) && count==0){ 33 tmap.put(dp[i],tmap.get(dp[i])+1); 34 count++; 35 }else if(diff==0 && !tmap.containsKey(dp[i])){ 36 Map<Integer,Integer> t = new HashMap<>(); 37 t.put(dp[i],2); 38 maps.put(diff,t); 39 } 40 }else{ 41 Map<Integer,Integer> t = new HashMap<>(); 42 t.put(dp[i],2); 43 maps.put(diff,t); 44 } 45 } 46 } 47 int max = 1; 48 for(Map.Entry<Integer,Map<Integer,Integer>> entry1:maps.entrySet()){ 49 Map<Integer,Integer> tmap = entry1.getValue(); 50 for(Map.Entry<Integer,Integer> entry2:tmap.entrySet()){ 51 Integer value = entry2.getValue(); 52 if(value>max){ 53 max = value; 54 } 55 } 56 } 57 System.out.println(max); 58 } 59 }