编程语言
首页 > 编程语言> > LeetCode算法题编号891“子序列宽度之和”算法分析和解题思路在前两篇随笔中(在找工作的途中)

LeetCode算法题编号891“子序列宽度之和”算法分析和解题思路在前两篇随笔中(在找工作的途中)

作者:互联网

我在研究该算法题的时候是先经过最笨的方法,然后慢慢优化得到计算量相对较少的算法。在研究该算法中断断续续的花了10个小时吧,基本都是晚上思考,白天为找工作准备。晚上思考算法并进行代码实现。

我也看了官方的答案,官方给的答案没有考虑数组中是否有重复的数。所以我这给了考虑重复的数的答案。如不准确还请告知。谢谢。

题目是:

给定一个整数数组 A ,考虑 A 的所有非空子序列。

对于任意序列 S ,设 S 的宽度是 S 的最大元素和最小元素的差。

返回 A 的所有子序列的宽度之和。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sum-of-subsequence-widths
在这题中考虑了:元素的排序,数组中是否有重复的数(不考虑这中情况,会使得最终结果与实际情况偏离。也就是在 考虑数组子系列的时候会重复计算)

首先统计数组中重复数的个数,并且用map集合封装。代码如下:

 1 //运用map集合统计数组中每个数出现的次数
 2         public static Map<Integer, Integer> getMap(Integer[] array){
 3             Map<Integer, Integer> map=new HashMap<>();
 4             Arrays.sort(array);    
 5             map.put(array[0], 1);
 6             for(int i=1;i<array.length;i++) {
 7                 if(array[i-1]==array[i]) {                        //判断左右是否相等,若相等则对应值的次数加一
 8                     map.put(array[i-1], map.get(array[i-1])+1);
 9                 }else {                                            //否则将不同的数输入map集合中
10                     map.put(array[i], 1);
11                 }
12             }
13             return map;
14         }

再将数组中不同的数封装在一个集合中。代码如下:

 1         //将不同的数存储在一个数组中   并且 按从小到大的顺序。
 2         public static Object[] getArrays(Integer[] array) {
 3             List<Integer> list=new ArrayList<>();
 4             Arrays.sort(array);    
 5             list.add(array[0]);
 6             for(int i=1;i<array.length;i++) {
 7                 if(array[i-1]==array[i]) {                        //判断左右是否相等,若相等则对应值的次数加一
 8                 }else {                                            
 9                     list.add(array[i]);    
10                 }
11             }
12             Object[] A=list.toArray();
13             return A;
14         }

再通过输入一个最大值,一个最小值。计算在最大值和最小值之间的数会出现的子序列的个数。代码如下(注释部分是为了校验在测试时出错的地方):

 1         //求两数之间的排列的次数
 2         public static int getNum(int i,int j) {                //i的数值小于j
 3             Map<Integer, Integer> map=getMap(array);
 4             Object[] A=getArrays(array);
 5             
 6             int num=1;
 7             for(int k=i+1;k<j;k++) {
 8                 num=num*(map.get(A[k])+1);
 9 //                num=(int) ((num+Math.pow(2, j-k-1))*map.get(A[k]));
10 //                num=(int) (num+map.get(A[k])*Math.pow(2, j-i-1));            
11                 //num=num+map.get(A[k]);
12 //                System.out.println("num1="+num);
13             }
14 //            System.out.println("i="+i+"   j="+j);
15 //            System.out.println(num);
16 //            System.out.println(2^(j-i)*num/2);
17             
18             System.out.println("tula"+Math.pow(2, 0)+"nima");
19             return num*map.get(A[i])*map.get(A[j]);
20         }

现在计算最终结果,代码如下:

 1         //得出最终值
 2         public static int getSum() {
 3             int sum=0;
 4             Object[] A=getArrays(array);
 5             for(int j=1;j<A.length;j++) {
 6                 for(int i=0;i<j;i++) {    //i的数值小于j
 7                     
 8                     sum=sum+getNum(i, j)*((int)A[j]-(int)A[i]);
 9                     //System.out.println("A[i]="+A[i]+"   i="+i+"  A[j]="+A[j]+"  j="+j+"  getNum="+getNum(i, j));
10                 }
11             }
12             
13             return sum;
14             
15         }

最后的main函数直接就可以得到最终结果。(注释部分是在思考过程中,然后慢慢优化)。我给的方法现在还不是最优化的。但是可以得出正确结果。

 1     public static void main(String[] args) {
 2         
 3         
 4         System.out.println(getSum());
 5         
 6         
 7         
 8         
 9 //        
10 //        
11 //        Map<Integer, Integer> map=new HashMap<>();
12 //        List<Integer> list=new ArrayList<>();                
13 //        Integer[] array= {66,2,3,99,25,1,6,5,6,6,8,8,8,9};
14 //        Arrays.sort(array);                                    //将数组中的数由小到大进行排序
15 //        
16 //        for(int i=0;i<array.length;i++) {
17 //            System.out.print(array[i]+"   ");
18 //        }
19 //        System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!");//打桩检测数据是否排序
20 //        
21 //        list.add(array[0]);
22 //        map.put(array[0], 1);                                //将第一个数输入map集合中
23 //        
24 //        for(int i=1;i<array.length;i++) {
25 //            if(array[i-1]==array[i]) {                        //判断左右是否相等,若相等则对应值的次数加一
26 //                map.put(array[i-1], map.get(array[i-1])+1);
27 //            }else {                                            //否则将不同的数输入map集合中
28 //                map.put(array[i], 1);
29 //                list.add(array[i]);                            //将数组中不同的数放在list集合中。
30 //            }
31 //        }
32 //        System.out.println(list);                            //打桩,检测list中的数据
33 //        System.out.println(map);                            //打桩,检测map中的数据
34 //        
35 //        Object[] A=list.toArray();                            //将集合转成数组
36 //        System.out.println(A[5]);                            //检测
37 //        
38 //        //准备工作完成。
39 //        
40 //        
41 //        int sum=0;                                            //宽度之和。
42 //        
43 //        for(int i=1;i<A.length;i++) {
44 //            for(int j=0;j<i;j++) {
45 //                
46 //            }
47 //        }
48 //        
49 //        
50 //        
51     }

 

标签:891,map,int,public,算法,static,数组,array,LeetCode
来源: https://www.cnblogs.com/zhou2420032204/p/13380529.html