问题陈述:
给定一个大小为 n 的整数数组 arr。
选择一个整数子序列并重新排列它们以形成一个循环序列,使得任意两个相邻整数(包括最后一个和第一个)之间的绝对差最多为 1。
找出可以选择的最大整数数。
笔记:
子序列是通过删除零个或多个元素而不改变剩余元素的顺序而形成的。
选定的整数可以按任意顺序重新排列。
该序列是循环的——最后一个整数和第一个整数被视为相邻的。
限制:
1 <= n <= 2 × 10^5
0 <= arr[i] <= 10^9
例子:
Input: arr = [4, 3, 5, 1, 2, 2, 1]
Output: 5
Explanation: maximum length subsequence is : [3, 1, 2, 2, 1], it can be rearranged to seq : [2, 1, 1, 2, 3] of length 5, note that the condition must be satisfied in circular also, means abs(seq[0] - seq[seq.length-1]) means abs(2-3) <= 0
Input: arr = [3, 7, 5, 1, 5]
Output: 2
Explanation: maximum length subsequence is : [5,5] of length 2
Input: arr = [2, 2, 3, 2, 1, 2, 2]
Output: 7
Explanation: maximum length subsequence is : [2,2,3,2,1,2,2] of length 7
Input: arr = [1,2,3,4,5]
Output = 2
Explanation: maximum length subsequence is : [1,2] or [2,3] or [3,4] or [4,5], so length is 2.
请注意,子序列也应该满足循环条件这是我的代码:
import java.util.*;
class Main {
public static int solve(int[] arr) {
Map<Integer, Integer> freq = new HashMap<>();
for (int num : arr) {
freq.put(num, freq.getOrDefault(num, 0) + 1);
}
int max = 0;
for (int num : freq.keySet()) {
int count = freq.get(num);
int countWithNext = freq.getOrDefault(num + 1, 0);
int countWithPrev = freq.getOrDefault(num - 1, 0);
max = Math.max(max, countWithPrev + count + countWithNext);
}
return max;
}
public static void main(String[] args) {
System.out.println(solve(new int[]{4,3,5,1,2,2,1})); // Expected: 5
System.out.println(solve(new int[]{3,7,5,1,5})); // Expected: 2
System.out.println(solve(new int[]{2,2,3,2,1,2,2})); // Expected: 7
System.out.println(solve(new int[]{1,2,3,4,5})); // Expected: 2
}
}
我能够找到最大长度子序列,但无法找到如何满足循环条件,因此对于测试用例 [1,2,3,4,5],我的代码返回 5 而不是 2。
此外,正如 John Bollinger 所评论的,该方法本身对于输入 [1,2,3,4,3,2] 失败
用较少的时间复杂度来解决这个问题的正确方法是什么?