删除最多一个元素后严格递增数组的 Java 程序测试

Posted

技术标签:

【中文标题】删除最多一个元素后严格递增数组的 Java 程序测试【英文标题】:Java Program testing for a strictly increasing array after removing at most one element 【发布时间】:2017-05-31 05:01:49 【问题描述】:

给定一个整数序列作为一个数组,确定是否可以通过从数组中删除不超过一个元素来获得一个严格递增的序列。

对于序列 = [1, 3, 2, 1],输出应该是 几乎增加序列(序列)=假; 这个数组中没有一个元素可以被移除以获得严格递增的序列。

对于序列 = [1, 3, 2],输出应该是 几乎IncreasingSequence(sequence) = true。 您可以从数组中删除 3 以获得严格递增的序列 [1, 2]。或者,您可以删除 2 以获得严格递增的序列 [1, 3]。

我为上面编写的代码如下所示,但对于序列 [1,2,3,4,3,6] 并不令人满意 实际输出 = 假 预期输出 = true

boolean almostIncreasingSequence(int[] sequence) 
        int max = Integer.MIN_VALUE, count = 0;
        boolean flag = true;
        for (int j = 0; j < sequence.length-1 ; j++)
              if ( max >= sequence [j] || sequence[j]>=sequence[j+1])
                 count++;
              
              else
                 max = sequence[j];
              if ( count > 1)
                 flag = false;
                 break;
              
                
        return flag; 

[时间限制] : 3000ms (java) [输入] : array.integer 序列

保证约束: 2 ≤ 序列.长度 ≤ 105, -105 ≤ 序列[i] ≤ 105。

[输出]:布尔值

如果可以从数组中删除一个元素以获得严格递增的序列,则返回 true,否则返回 false。

【问题讨论】:

您期望得到哪个答案,得到哪个答案?尝试使用调试器运行并检查流程偏离预期的位置。 我期待该序列的真实价值,但我得到了错误。 现在您需要找出为什么计数为 2。计数第一次增加的时间是什么时候?第二次是什么时候?这些真的是不同的问题,还是您将一个问题计算两次? 问题是当 j 达到 4 时。我没有找到解决它的逻辑。如果我对序列 [1,2,3,4,3,6] 进行更正,则 [1,2,1,2] 的测试用例不令人满意。 max 的想法非常好。你只需要确保检查完整的数组。 【参考方案1】:

这是可以通过从原始程序中删除内容来修复的错误之一:

boolean almostIncreasingSequence(int[] sequence) 
    int max = Integer.MIN_VALUE, count = 0;
    boolean flag = true;
    for (int j = 0; j < sequence.length; j++)
          if ( max >= sequence[j])
             count++;
          
          max = sequence[j];
          if ( count > 1)
             flag = false;
             break;
          
            
    return flag; 

原版的主要问题是,同一个乱序的地方被发现了两次。只需删除其中一项检查,同时添加一次循环迭代即可解决此问题。

【讨论】:

@NenadDordevic 哎呀,你是对的。还有一件事要从原始程序中删除。谢谢。【参考方案2】:

根据您的方法,我建议您在 for 循环中进行以下修改:

对于(……):

if s[i] >= s[i+1] count++
else if max >= s[i] count++
else max = s[i]

for循环结束后: 如果计数 > 1 返回 false 否则返回真

【讨论】:

除了所有的语法错误,这仍然会在 [1,2,3,4,3,6] 上给出 false。 是的,你是对的,我没有仔细考虑(代码只是伪代码)【参考方案3】:

使用简单的蛮力方法,创建一个返回缺少一个元素的数组的方法,然后检查该数组以查看它是否在增加。围绕所有这些的循环应该可以工作。

public static void main(String[] args) 
  if (IncreasingSequence(new int[] 1,2,3,4,3,6))
    System.out.println("By removing one element the array is increasing");
  else
    System.out.println("By removing one element the array is Not increasing");


private static boolean IncreasingSequence(int[] sequence) 
  int[] nextArray;
  for (int i = 0; i < sequence.length; i++) 
      nextArray = MinusOneElement(sequence, i);
      if (CheckSequenceIncreasing(nextArray)) 
         return true;
     
  return false;


private static boolean CheckSequenceIncreasing(int[] sequence) 
    for (int i = 0; i < sequence.length - 1; i++) 
       if (sequence[i] >= sequence[i + 1]) 
           return false;
    
  
  return true;


private static int[] MinusOneElement(int[] sequence, int elementToRemove) 
   int[] newArray = new int[sequence.length - 1];
   int index = 0;
   for (int i = 0; i < sequence.length; i++) 
        if (i != elementToRemove) 
            newArray[index] = sequence[i];
            index++;
        
   
   return newArray;

【讨论】:

谢谢,您的代码适用于所有测试用例。但它增加了分配给我的时间限制,即 3000 毫秒。有没有优化的方法? 对不起,这是我现在能想到的最好的了。我明天再检查一次。如果您不创建一个元素较少的新数组(我猜这是减慢速度),而是循环遍历原始数组,那么您将不得不在循环内进行一些特殊的杂耍以忽略该元素,因为它显然是至少i 在一次迭代中,可能在另一次迭代中i + 1【参考方案4】:

这个程序会遍历数组的元素,比较当前是否大于或等于下一个。如果是这样,它会比较当前周围的元素,因为它可能会被删除。它会比较 next 周围的元素,因为它可能会被删除。如果删除 current 或 next 不会使增加的数组返回 false。

public static void main(String[] args) 
    boolean almostIncreasingSequence = almostIncreasingSequence(new int[]  1, 2, 3, 4, 99, 4, 3 );
    System.out.println(almostIncreasingSequence);


static boolean almostIncreasingSequence(int[] sequence) 
    int removeCount = 0;
    for (int i = 0; i < sequence.length - 1; i++) 
        int current = sequence[i];
        int next = sequence[i + 1];

        if (current >= next) 
            removeCount++;
            // Try to remove current. Skip removed element(current). Check
            // if previous is less than next element around current
            // if i is 0 there is no previous element
            // if removeCurrent is true it is possible to remove it and
            // arrays stays increasing
            boolean removeCurrent = i == 0 || sequence[i - 1] < next;
            // if removeNext is true it is possible to remove it and arrays
            // stays increasing
            boolean removeNext = i + 1 == sequence.length - 1 || current < sequence[i + 2];

            if (!removeCurrent && !removeNext)
                // if current is removed and array isn't increasing and if
                // next is removed and array is not increasing,
                // increment removeCount to return false
                removeCount++;
        
        if (removeCount > 1) 
            return false;
        
    
    return true;

它满足所有给定的测试用例。

【讨论】:

在这种情况下,您必须检查是否有任何先前的元素不大于 t 它不能满足所有测试用例。例如 [1,2,1,2] 预期为假 谢谢,它适用于上述测试用例。但这并不能让所有人满意。 序列:[10, 1, 2, 3, 4, 5] 输出:false 预期输出:true 序列:[1, 2, 3, 4, 99, 5, 6] 输出:false预期输出:true 序列:[123, -17, -5, 1, 2, 3, 12, 43, 45] 输出:false 预期输出:true 我修改了程序,它对提供的序列给出了预期的结果【参考方案5】:

对于 kotlin 程序员

fun almostIncreasingSequence(sequence: MutableList<Int>): Boolean 



var removeCount = 0;

var i = 0;

while  ( i < sequence.size - 1) 

var current = sequence[i];

var next = sequence[i + 1];

if (current >= next) 

removeCount++;

var removeCurrent : Boolean= i == 0 || sequence[i - 1] < next;

var removeNext : Boolean = i + 1 == sequence.size - 1 || current < sequence[i + 2];

if (!removeCurrent && !removeNext)

    removeCount++;

      

      if (removeCount > 1) 

                    return false;

        

      i++

    

    return true;  

 

【讨论】:

以上是关于删除最多一个元素后严格递增数组的 Java 程序测试的主要内容,如果未能解决你的问题,请参考以下文章

308删除一个元素使数组严格递增

3627删除一个元素使数组严格递增

2022-08-22:给定一个数组arr,长度为n,最多可以删除一个连续子数组, 求剩下的数组,严格连续递增的子数组最大长度。 n <= 10^6。 来自字节。5.6笔试。

LeetCode 第 55 场双周赛 / 第 247 场周赛

Java 求解最长递增子序列

Java 求解最长递增子序列