英文:
Longest subArray with no more than two distinct values that differ by no more than 1
问题
给定一个整数数组,要求找出包含不超过两个不同值的最长子数组的长度,使得这两个不同的值的差值不超过1。
例如:
arr = [0, 1, 2, 1, 2, 3] -> 长度 = 4; [1, 2, 1, 2]
arr = [1, 2, 3, 4, 5] -> 长度 = 2; [1, 2]
arr = [1, 1, 1, 3, 3, 2, 2] -> 长度 = 4; [3, 3, 2, 2]
我有以下代码:
public static int longestSubarray(List<Integer> arr) {
int max = 0;
Set<Integer> set = new HashSet<>();
int i = 0;
int j = 1;
while (i < arr.size() - 1) {
set.add(arr.get(i));
while (j < arr.size() && Math.abs(arr.get(i) - arr.get(j)) < 2) {
if (!set.contains(arr.get(j))) {
if (set.size() == 2) {
break;
} else {
set.add(arr.get(j));
}
}
++j;
}
max = Math.max(max, j - i);
j = ++i + 1;
set.clear();
}
return max;
}
是否有更好的解决方案?
英文:
Given an array of integers what is the length of the longest subArray containing no more than two distinct values such that the distinct values differ by no more than 1
For Example:
arr = [0, 1, 2, 1, 2, 3] -> length = 4; [1,2,1,2]
arr = [1, 2, 3, 4, 5] -> length = 2; [1,2]
arr = [1, 1, 1, 3, 3, 2, 2] -> length = 4; [3,3,2,2]
I have such code
public static int longestSubarray(List<Integer> arr) {
int max = 0;
Set<Integer> set = new HashSet<>();
int i = 0;
int j = 1;
while (i < arr.size() - 1) {
set.add(arr.get(i));
while (j < arr.size() && Math.abs(arr.get(i) - arr.get(j)) < 2) {
if (!set.contains(arr.get(j))) {
if (set.size() == 2) {
break;
} else {
set.add(arr.get(j));
}
}
++j;
}
max = Math.max(max, j - i);
j = ++i + 1;
set.clear();
}
return max;
}
Can there be a better solution?
答案1
得分: 6
是的。这是一个具有O(n)
时间复杂度和O(1)
空间复杂度的动态规划程序。思路是,通过查看可能包含较高元素的以A[i-1]
结尾的最佳序列,以及可能包含较低元素的以A[i-1]
结尾的最佳序列,我们可以得出以A[i]
结尾的序列的答案。
JavaScript代码:
function f(A){
if (A.length < 2)
return A.length;
let best = 1;
let bestLower = 1;
let bestHigher = 1;
for (let i=1; i<A.length; i++){
if (A[i] == A[i-1]){
bestLower = bestLower + 1;
bestHigher = bestHigher + 1;
} else if (A[i] - 1 == A[i-1]){
bestLower = 1 + bestHigher;
bestHigher = 1;
} else if (A[i] + 1 == A[i-1]){
bestHigher = 1 + bestLower;
bestLower = 1;
} else {
bestLower = 1;
bestHigher = 1;
}
best = Math.max(best, bestLower, bestHigher);
}
return best;
}
arrays = [
[0, 1, 2, 1, 2, 3], // 长度为 4; [1,2,1,2]
[1, 2, 3, 4, 5], // 长度为 2; [1,2]
[1, 1, 1, 3, 3, 2, 2] // 长度为 4; [3,3,2,2]
];
for (let arr of arrays){
console.log(JSON.stringify(arr));
console.log(f(arr));
}
英文:
Yes. Here's a dynamic program with O(n)
time and O(1)
space. The idea is that we can get the answer for the sequence ending at A[i]
by looking at the best sequence ending at A[i-1]
that possibly included higher elements, and the best sequence ending at A[i-1]
that possibly included lower elements.
JavaScript code:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function f(A){
if (A.length < 2)
return A.length;
let best = 1;
let bestLower = 1;
let bestHigher = 1;
for (let i=1; i<A.length; i++){
if (A[i] == A[i-1]){
bestLower = bestLower + 1;
bestHigher = bestHigher + 1;
} else if (A[i] - 1 == A[i-1]){
bestLower = 1 + bestHigher;
bestHigher = 1;
} else if (A[i] + 1 == A[i-1]){
bestHigher = 1 + bestLower;
bestLower = 1;
} else {
bestLower = 1;
bestHigher = 1;
}
best = Math.max(best, bestLower, bestHigher);
}
return best;
}
arrays = [
[0, 1, 2, 1, 2, 3], // length = 4; [1,2,1,2]
[1, 2, 3, 4, 5], // length = 2; [1,2]
[1, 1, 1, 3, 3, 2, 2] // length = 4; [3,3,2,2]
];
for (let arr of arrays){
console.log(JSON.stringify(arr));
console.log(f(arr));
}
<!-- end snippet -->
答案2
得分: 4
using System.IO;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<int> arr = new List<int>() { 0, 1, 2, 1, 2, 3 };
List<int> set = new List<int>();
int n = arr.Count;
int max = 1;
int i, j;
for (i = 0; i < n - 1; i++)
{
set.Add(arr[i]);
for (j = i + 1; j < n;)
{
if (Math.Abs(arr[i] - arr[j]) < 2)
{
if (!set.Contains(arr[j]))
{
if (set.Count == 2)
break;
else
set.Add(arr[j]);
}
}
else
break;
j++;
}
max = Math.Max(max, j - i);
set.Clear();
}
Console.WriteLine(max);
}
}
英文:
C# code:
using System.IO;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<int> arr = new List<int>(){ 0, 1, 2, 1, 2, 3};
List<int> set = new List<int>();
int n = arr.Count;
int max = 1;
int i,j;
for(i=0 ; i<n-1; i++)
{
set.Add(arr[i]);
for(j=i+1; j<n; )
{
if(Math.Abs(arr[i]-arr[j])<2)
{
if(!set.Contains(arr[j]))
{
if(set.Count == 2)
break;
else
set.Add(arr[j]);
}
}
else
break;
j++;
}
max = Math.Max(max,j-i);
set.Clear();
}
Console.WriteLine(max);
}
}
答案3
得分: 1
参考这篇 GFG 帖子,并在其中将 X 替换为 1。
链接:https://www.geeksforgeeks.org/longest-subarray-in-which-absolute-difference-between-any-two-element-is-not-greater-than-x/
英文:
refer to this GFG Post
and there replace X by 1
答案4
得分: -3
static int solution(List<Integer> arr) {
int subArrStart = 0;
int changedSubArrStart = 0;
int longSubArrayLen = 0;
int currSubArrayLen = 0;
for (int i = 0; i < arr.size(); i++) {
if (arr.get(subArrStart) == arr.get(i)) {
currSubArrayLen++;
} else if (Math.abs(arr.get(subArrStart) - arr.get(i)) == 1) {
if (subArrStart == changedSubArrStart) {
changedSubArrStart = i;
}
currSubArrayLen++;
} else if (Math.abs(arr.get(changedSubArrStart) - arr.get(i)) == 1) {
subArrStart = changedSubArrStart;
currSubArrayLen = i - subArrStart + 1;
} else {
subArrStart = i;
changedSubArrStart = i;
currSubArrayLen = 1;
}
longSubArrayLen = Math.max(longSubArrayLen, currSubArrayLen);
}
return longSubArrayLen;
}
英文:
Java solution with O(n) time complexity
static int solution(List<Integer> arr) {
int subArrStart = 0;
int changedSubArrStart = 0;
int longSubArrayLen = 0;
int currSubArrayLen = 0;
for (int i = 0; i < arr.size(); i++) {
if (arr.get(subArrStart) == arr.get(i)) {
currSubArrayLen++;
} else if (Math.abs(arr.get(subArrStart) - arr.get(i)) == 1) {
if (subArrStart == changedSubArrStart) {
changedSubArrStart = i;
}
currSubArrayLen++;
} else if (Math.abs(arr.get(changedSubArrStart) - arr.get(i)) == 1) {
subArrStart = changedSubArrStart;
currSubArrayLen = i - subArrStart + 1;
} else {
subArrStart = i;
changedSubArrStart = i;
currSubArrayLen = 1;
}
longSubArrayLen = Math.max(longSubArrayLen, currSubArrayLen);
}
return longSubArrayLen;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论