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∗log2N),空间复杂度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∗log2n),双指针遍历两遍数组,时间复杂度O(2N), 最终时间复杂度O(
n
∗
l
o
g
2
n
n*log_2{n}
n∗log2n),空间复杂度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;
}
}