java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846
子序列要尽可能长,并且最大值和最小值之间的差,必须为1。所以这道题的迷惑点在于,最大值最小值之间,可以插入任意个数的元素。 但是只要我们把数字列出来,2,2,2,3,3,3,你会发现,根本不能插入任何其它数字,例如2,2,2,1,3,3,3, 此时的差可不是1,而是3-1=2了。 因此,这道题可以理解为,找数组中两个数,相差为1,并且两个元素的出现次数相加为最多。 法一,hash表:时间复杂度O(n),空间复杂度O(n). 可以使用hash表,记录每个元素的出现次数,如果两个元素相差为1,就记录它们的出现次数,最终返回最大的出现次数。 法二,排序+双指针:时间复杂度O( n ∗ l o g 2 N n*log_2{N} n ∗ l o g 2 N ),空间复杂度O(1). 先对数组排序,然后left指针指向前一个元素,right指针指向后一个元素,如果相差为1,记录它们的长度
法一:hash表
class Solution { public int findLHS ( int [ ] nums) { Map < Integer , Integer > map = new HashMap < > ( ) ; int res = 0 ; for ( int num: nums) map. put ( num, map. getOrDefault ( num, 0 ) + 1 ) ; for ( int key: map. keySet ( ) ) { if ( map. containsKey ( key + 1 ) ) res = Math . max ( res, map. get ( key) + map. get ( key+ 1 ) ) ; } return res; }
}
法二:排序+双指针,排序使用快速排序,时间复杂度O( n ∗ l o g 2 n n*log_2{n} n ∗ l o g 2 n ),双指针遍历两遍数组,时间复杂度O(2N), 最终时间复杂度O( n ∗ l o g 2 n n*log_2{n} n ∗ l o g 2 n ),空间复杂度O(1)。
class Solution { public int findLHS ( int [ ] nums) { Arrays . sort ( nums) ; int left = 0 , right = 0 ; int cnt = 0 , max = 0 ; while ( right < nums. length) { while ( nums[ left] + 1 < nums[ right] ) left++ ; if ( nums[ right] == nums[ left] + 1 ) { while ( right< nums. length && nums[ right] == nums[ left] + 1 ) right++ ; right-- ; cnt = right - left + 1 ; max = Math . max ( max, cnt) ; } right++ ; } return max; }
}