java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846
方法一:hash表
此方法是工作中时间可以使用的,因为它的时间和空间复杂度都相对平衡,也较低。下面介绍的方法二,工作中是坚决不可以使用的,因为会造成大量的空间浪费。
先遍历一遍数组,记录每个元素的出现次数,起始下标和结尾下标 然后遍历hash表,找到最大出现次数的元素,然后通过len = 结尾下标 - 起始下标 +1获取其长度 如果遇到相同出现次数的元素,选择长度更小的作为答案(题目要求)
class Solution { public int findShortestSubArray ( int [ ] nums) { Map < Integer , int [ ] > map = new HashMap < Integer , int [ ] > ( ) ; int n = nums. length; for ( int i = 0 ; i < n ; i++ ) { if ( map. containsKey ( nums[ i] ) ) { map. get ( nums[ i] ) [ 0 ] ++ ; map. get ( nums[ i] ) [ 2 ] = i; } else map. put ( nums[ i] , new int [ ] { 1 , i, i} ) ; } int maxNum = 0 , minLen = 0 ; for ( Map. Entry < Integer , int [ ] > entry: map. entrySet ( ) ) { int [ ] arr = entry. getValue ( ) ; if ( maxNum < arr[ 0 ] ) { maxNum = arr[ 0 ] ; minLen = arr[ 2 ] - arr[ 1 ] + 1 ; } else if ( maxNum == arr[ 0 ] ) { if ( minLen> arr[ 2 ] - arr[ 1 ] + 1 ) minLen = arr[ 2 ] - arr[ 1 ] + 1 ; } } return minLen; }
}
方法二:数组下标线性索引
此方法的做题效率更高,对于某些题目来说,确实无论是实际应用和做题的角度来说,都是不错的方法。但不是这道题应该使用的方法。对于这道题也只能做题时可以使用一下了。因为它用数组中的值的范围,作为数组x的下标,数组x作为hash表,来进行常数级的存取。但是假设,数组中存储的元素范围是1 ~ 100000000,那么就需要申请长度为100000000的数组空间。假设有一个数组需要处理,[1,2,3,4,4,4,10000000000],如果使用正经的hash表,只需要7个空间。而使用这种方法,空间复杂度就是10000000000。如果实际应用场景你写出这种代码,100%会被辞退的。因此,这个方法,对于这道题,只能大家做题使用,千万不要放到工作场景中。
时间复杂度O(n), 空间复杂度O(maxValue - minValue + 1),空间复杂度是数组中值的取值范围。真的了解一下即可,不推荐使用,纯粹在投机取巧
class Solution { public int findShortestSubArray ( int [ ] nums) { int min= Integer . MAX_VALUE ; int max= Integer . MIN_VALUE ; for ( int i: nums) { max= Math . max ( max, i) ; min= Math . min ( min, i) ; } int [ ] count= new int [ max- min+ 1 ] ; int maxCount= 0 ; for ( int i: nums) { maxCount= Math . max ( maxCount, ++ count[ i- min] ) ; } if ( maxCount== 1 ) { return 1 ; } int res= nums. length; int start, end= nums. length- 1 ; int num= 0 ; for ( int i= 0 ; i< count. length; i++ ) { if ( count[ i] != maxCount) { continue ; } start= 0 ; end= nums. length- 1 ; num= min+ i; while ( start< end&& nums[ start] != num) { start++ ; } while ( start< end&& nums[ end] != num) { end-- ; } res= Math . min ( res, end- start+ 1 ) ; } return res; }
}