【问题标题】:Remove last occurrence of a specific integer from an array从数组中删除最后一次出现的特定整数
【发布时间】:2020-06-17 13:03:38
【问题描述】:

由于某种原因,我的解决方案并不完整。我从隐藏的规格测试中获得了 80/100。

  1. 我的解决方案有什么问题?可能有一个我没有想到的用例。
  2. 使用 ArrayList 而不是数组会如何改变空间/时间复杂度?
  3. 有没有更好的方法来解决这个问题?

我当前的解决方案处理:

  • 一个空的输入数组
  • 输入数组中的负/正整数值
  • 输入数组中的重复项
  • 已排序/未排序的输入数组

说明:

编写一个 Java 方法 removeLastOccurrence(int x, int[] arr),它从给定的整数元素数组 arr 中删除给定整数元素 x 的最后一次出现。

该方法应返回一个新数组,该数组包含给定数组 arr 中的所有元素,但最后一次出现的元素 x 除外。其余元素应以相同的顺序出现在输入和返回的数组中。

右边的代码显示了一个代码框架,其中仍然缺少一个静态方法的实现。提供此实现并通过自己编写更多测试或使用提供的测试和规范测试来检查它是否正确。

我的代码:

class RemoveLastOccurrenceArray {

    /**
     * Takes the array and the last occurring element x,
     * shifting the rest of the elements left. I.e.
     * [1, 4, 7, 9], with x=7 would result in:
     * [1, 4, 9].
     *
     * @param x   the entry to remove from the array
     * @param arr to remove an entry from
     * @return the updated array, without the last occurrence of x
     */
    public static int[] removeLastOccurrence(int x, int[] arr) {

        // if arr == null return null;
        if (arr == null || arr.length == 0) return arr;

        // return a new array which will be size arr.legnth-1
        int[] res = new int[arr.length - 1];

        // introduce an int tracker which keep tracks of the index of the last occurrence of x
        int last_index = -1;

        // traverse through the array to get the index of the last occurrence
        for (int i = 0; i < arr.length; i++) if (arr[i] == x) last_index = i;

        int i = 0, j = 0;

        // copying elements of array from the old one to the new one except last_index
        while (i < arr.length) {
            if (i == last_index) {
                if (i++ < res.length) {
                    res[j++] = arr[i++];
                }
            } else res[j++] = arr[i++];
        }

        // if we pass in x which is not in the array just return the original array
        if (last_index == -1) return arr;

        // are there duplicates in the array? - WORKS
        // does the array have negative numbers? - WORKS
        // Is the array sorted/unsorted - WORKS

        return res;
    }
}

通过单元测试

import static org.junit.Assert.*;

import org.junit.*;

public class RemoveLastOccurrenceArrayTest {
    @Test
    public void testRemoveArray_Empty() {
        int[] array = new int[0];
        assertEquals(0, RemoveLastOccurrenceArray.removeLastOccurrence(5, array).length);
    }

    @Test
    public void testFirstSimple() {
        int[] input = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int[] result = {2, 3, 4, 5, 6, 7, 8, 9, 10};
        assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(1, input));
    }

    @Test
    public void testLastSimple() {
        int[] input = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int[] result = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(10, input));
    }

    @Test
    public void testPositiveInMiddleDuplicate() {
        int[] input = {1, 2, 3, 3, 4, 5};
        int[] result = {1, 2, 3, 4, 5};
        assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(3, input));
    }

    @Test
    public void testNegativeFirst() {
        int[] input = {-3, -1, 2, -3, 3, 4, 5, 0};
        int[] result = {-3, -1, 2, 3, 4, 5, 0};
        assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(-3, input));
    }

    @Test
    public void testLasttoRemove() {
        int[] input = {1, 4, 7, 9};
        int[] result = {1, 4, 7};
        assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(9, input));
    }
}

【问题讨论】:

  • 想想这个极端情况:[1,4,7,9] 和目标x=9。您的代码将是一个死循环,因为 i 永远不会自行增加。
  • @ZhaoGang 感谢您的评论,但是您说的不正确。 i 在 2 个场景中增加。 if (i++ &lt; res.length)else res[j++] = arr[i++]; 和上面的极端情况处理正确,在发布问题之前已经用 Java 单元测试进行了测试。
  • 但是在您发布的代码中,if 子句和 else 子句不匹配。 else 子句匹配 if (i == last_index) { @gforghieri

标签: java algorithm


【解决方案1】:

为什么不尝试向后迭代?

for(int i = arr.length; i => 0; i--)
{ 
   if (arr[i] == x)
   {
       return ArrayUtils.remove(arr, i)
    }
}

然后,找到索引后,可以使用 Apache Commons ArrayUtils remove 命令删除该项目

【讨论】:

  • 感谢您的回答,但练习的重点是 "该方法应返回 一个新数组,其中包含给定数组 arr 中除最后一次出现的所有元素元素 x"获取数组和最后出现的元素 x,将其余元素向左移动。此外,通常我必须在一个孤立的在线环境中解决这个练习,在这个环境中我无法访问除本机 Java utils 以外的依赖项。
【解决方案2】:

这就是答案,非常感谢!

另外,如果没有 x 可以找到,你的会崩溃……我的不会。也许这就是二十个标记的去向?

我已经在检查这个,但在我的代码中为时已晚。所以我只好搬家了

if (last_index == -1) return arr; 在 while 循环之前,我得到了 100/100 的分数。


你的教授更喜欢这个吗?只是另一种方式,我认为没有比你的答案更有效的了。但也许他们喜欢看到使用的 java 类...

你的教授没有告诉你你在哪里丢分吗?如果他们不告诉你他们对满分的期望,你就无法提高。但这是另一种方式……再说一次,在我看来并没有更好,而且不值二十多分。我会发布它,因为它是“另一种方式”。

    public int[] removeLastOccurrence2(int x, int[] arr) {

        // if arr == null return null;
        if (arr == null || arr.length == 0) return arr;

        // Fill an ArrayList with your initial array ...

        java.util.List list = new java.util.ArrayList(arr.length);

        for (int i=0; i<arr.length; i++) {
            list.add(arr[i]);
        }

        int[] res;

        // Now ... use ArrayList methods to do the work.

        // Also, if there is no x to find, yours crashes ... mine doesn't.
        // Maybe that's where the twenty marks went?

        if ( list.lastIndexOf(x) != -1 ) { // This screens for no x found at all ...

             list.remove( list.lastIndexOf(x) ); // Done!

             // Make a new array to return.
             res = new int[list.size()];
             for (int i=0; i<list.size(); i++) {
                 res[i] = (int) list.get(i);
             }

        } else {

            // No 'x' found, so just return the original array.
            res = arr;
        }        

       return res;
    }

【讨论】:

  • 感谢您的回答,我必须在孤立的 Web 环境中提供解决方案,除了 0/100 的分数之外没有任何反馈。您的解决方案确实得到了 100/100,因此我的解决方案无法处理一个案例。 你能想到一个输入值 x 和 arr 的测试用例,我的代码会失败而你的代码会通过
猜你喜欢
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
  • 2021-05-08
  • 2020-12-18
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 2013-11-01
相关资源
最近更新 更多