我现在遇到了以下问题。我没有完美的逻辑。以下是问题:
给定一个整数序列作为数组,确定它是否为 通过从数组中删除不超过一个元素,可以获得严格增加的序列。
示例1:
For sequence = [1, 3, 2, 1], the output should be false.
There is no one element that can be removed to get a strictly an increasing sequence
示例2:
For sequence = [1, 3, 2], the output should be true.
You can remove 3 or 2 to get the strictly increasing sequence [1, 2] or [1,3] respectively
我尝试过如下:
boolean almostIncreasingSequence(int[] sequence) {
ArrayList<Integer> list = new ArrayList<>();
for(int i=0; i<sequence.length;i++) {
list.add(sequence[i]);
}
int omittedCounter = 0;
boolean status = true;
for(int i=1; i<list.size();i++) {
if(list.get(i-1) >= list.get(i)) {
omittedCounter ++;
list.remove(i-1);
break;
}
}
if (omittedCounter > 0) {
for(int i=1; i<list.size();i++) {
if(list.get(i-1) >= list.get(i)) {
omittedCounter ++;
list.remove(i-1);
break;
}
}
}
if (omittedCounter > 1) {
status = false;
}
return status;
}
但是当我得到这个序列时,我遇到了麻烦: [1, 2, 3, 4, 3, 6]
Output: false
Expected Output: true
答案 0 :(得分:3)
这可以在线性时间O(n)
和常数空间O(1)
中进行。
public static boolean analyse(int[] sequence) {
if (sequence.length <= 2) return true;
int a = sequence[0];
int b = sequence[1];
int drops = 0;
if (a >= b) {
drops++;
a = b - 1; //drop a, keeping the smallest, fake a value for the first loop
}
// consider 3 items at a time, a, b & c
for (int i = 2; i < sequence.length; i++) {
int c = sequence[i];
if (a < b && b < c) {
// all good, move on
a = b;
b = c;
continue;
}
// we'll have to drop one of them
drops++;
if (drops > 1) return false;
// which one will we drop, b or c?
if (a < c) {
// drop b (a,b -> a,c)
b = c;
} // else drop c (a,b -> a,b)
}
return true;
}
答案 1 :(得分:1)
实现这一目标的一种方法是做这样的事情(在最糟糕的情况下约O(n*2)
):
static boolean analyse(int[] sequence){
int counter =0;
//LinkedHashSet Keep Order But Remove Duplicates
Set<Integer> set = new LinkedHashSet<>();
//Copy Array To The Set
for(int i=0; i<sequence.length; i++){
set.add(sequence[i]);
}
//Count How Many Duplicates Found
counter+=(sequence.length-set.size());
if(counter>1){return false;}
Integer[] seq = set.toArray(new Integer[set.size()]);
// Loop Through The Array
// If Any Breaks The Rule -> Increment Counter
for(int i=0; i<seq.length-1; i++){
if(i==0 && seq[i]>seq[i+1]) {counter++;}
if(i!=0 && !(seq[i]<seq[i+1]&&seq[i-1]<seq[i])){counter++;}
if(counter>1){return false;}
}
return true;
}
<强>测试强>
int [] s = {1,2,3,4,3,5};
int [] s1 = {1,2,3,4,3,6,1};
int [] s2 = {1,2,3,4,3,6};
int [] s3 = {1,2,3,10,10,6};
int [] s4 = {1,2,3,10,3,6};
System.out.println(analyse(s));
System.out.println(analyse(s1));
System.out.println(analyse(s2));
System.out.println(analyse(s3));
System.out.println(analyse(s4));
<强>输出强>
true
false
true
false
false
答案 2 :(得分:0)
我有一个答案,其时间复杂度为N * Log(N)。我们将找出最长的几乎增加的序列并检查它是否等于或大于(N-1),然后我们将返回true,否则为false。
结帐:
public int FindIndex(int A[], int l, int r, int key) {
while (r - l > 1) {
int m = l + (r - l) / 2;
if (A[m] >= key) r = m;
else l = m;
}
return r;
}
public boolean LongestIncreasingSubsequenceLength(int A[], int size)
{
int[] Seq = new int[size];
int len;
Seq[0] = A[0];
len = 1;
for (int i = 1; i < size; i++) {
if (A[i] < Seq[0]) Seq[0] = A[i];
else if (A[i] > Seq[len - 1]) Seq[len++] = A[i];
else Seq[FindIndex(Seq, -1, len - 1, A[i])] = A[i];
}
return len >= size - 1;
}
答案 3 :(得分:-2)
在Python3中,
def almostIncreasingSequence(sequence):
# checking whether there are more than one repeated element, this is to decrease complexity! As we need strictly increasing order after removal of one item, there cannot be more than one repeated item if only removing that is to give us the strictly increasing order.
if len(sequence) - len(set(sequence)) > 1:
return False
# delete/pop one element from the both copies of list, sort one list and compare with the other copy to check whether both copies are equal
for i, n in enumerate(sequence):
temp = sequence.copy()
temp2 = sequence.copy()
temp.pop(i)
temp2.pop(i)
temp.sort()
if temp == temp2:
return True
return False