使用分治法向后检查一个数组是否等于另一个数组

发布于 2025-01-18 15:34:59 字数 1404 浏览 3 评论 0原文

我一直在尝试创建一个简单的函数来检查数组是否与另一个数组反转相同。

例如,比较 [0, 1, 2] 和 [2, 1, 0] 将返回 true,但比较 [0, 1, 2]< /code> 和 [2, 1, 1] 将返回 false

我还尝试使用分而治之的方法,递归地使用函数。

这是我编写的代码,但它没有按预期工作,在应该返回 true 时返回 false

public class ReverseCheck {

    // Check if an array is the reverse of another array
    // Use divide and conquer
    public static boolean isReverse(int[] a, int[] b) {
        if (a.length != b.length) {
            return false;
        }
        return isReverse(a, b, 0, a.length - 1);
    }

    private static boolean isReverse(int[] a, int[] b, int start, int end) {
        if (start == end) {
            return a[start] == b[end];
        }
        int mid = (start + end) / 2;
        return isReverse(a, b, start, mid) && isReverse(a, b, mid + 1, end);
    }

    public static void main (String[] args) {
        int[] a = {1, 2, 3, 4, 5, 6};
        int[] b = {6, 5, 4, 3, 2, 1};
        int[] c = {1, 2, 3, 4, 5, 6, 7};
        int[] d = {6, 5, 5, 3, 2, 1};
        System.out.println(isReverse(a, b)); // Should return true, returns false
        System.out.println(isReverse(a, c)); // Should return false, returns false
        System.out.println(isReverse(a, d)); // Should return false, returns false
    }

}

I've been trying to make a simple function which checks if an array is the same as another array reversed.

For instance, comparing [0, 1, 2] and [2, 1, 0] would return true, but comparing [0, 1, 2] and [2, 1, 1] would return false.

I am also trying to use the divide and conquer method, using function recursively.

This is what I have coded, but it doesn't work as intended, returning false when it should return true:

public class ReverseCheck {

    // Check if an array is the reverse of another array
    // Use divide and conquer
    public static boolean isReverse(int[] a, int[] b) {
        if (a.length != b.length) {
            return false;
        }
        return isReverse(a, b, 0, a.length - 1);
    }

    private static boolean isReverse(int[] a, int[] b, int start, int end) {
        if (start == end) {
            return a[start] == b[end];
        }
        int mid = (start + end) / 2;
        return isReverse(a, b, start, mid) && isReverse(a, b, mid + 1, end);
    }

    public static void main (String[] args) {
        int[] a = {1, 2, 3, 4, 5, 6};
        int[] b = {6, 5, 4, 3, 2, 1};
        int[] c = {1, 2, 3, 4, 5, 6, 7};
        int[] d = {6, 5, 5, 3, 2, 1};
        System.out.println(isReverse(a, b)); // Should return true, returns false
        System.out.println(isReverse(a, c)); // Should return false, returns false
        System.out.println(isReverse(a, d)); // Should return false, returns false
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

丶视觉 2025-01-25 15:34:59

解决方案中有几个问题:

  • 基本案例在其中存在逻辑缺陷。返回值代表比较a [start] == b [end]时的结果。这不是验证一个 array 的正确方法是另一个反向复制。让我们考虑两个数组 a = [1,2,3]b = [3,2,1]。我们必须检查a [0] == b [2]a [1] == b [1]a [2] == B [0]。如您所见,当索引相等时,只有一次 ,并且只有长度是奇数的,如果长度是所有元素中的索引,则。

  • 第二个问题是您采取的整体方法。对于此问题,我们必须检查所有值。鸿沟和征服方法在这里是徒劳的,因为我们无法减少操作量,在最坏的情况下,需要比较每对值。

我建议通过回溯解决这个问题,只需在每个方法调用中通过1移动两个数组的索引, 而无需使用鸿沟和征服,因为我们无法从中受益。

首先,让我们修复递归的基本案例

在两种情况下,递归应终止:当两对中的值不匹配并达到最后的有效索引时。

当第一种情况的条件是,当与当前索引相对应的值不等时,将看起来像:

if (a[start] != b[end]) return false;

第二部分可能是这样写的:

if (start == a.length - 1) return a[start] == b[end];

if (start == a.length - 1) return true;

两者的含义几乎相同 - 我们设法比较了所有对一对值(或最后一对正在比较)。第一个版本稍好一些,它会备用一个方法调用。

递归情况中,我们只是通过传递start1结束减少来调用该方法通过1

private static boolean isReverse(int[] a, int[] b, int start, int end) {
    if (start == a.length - 1) {
        return a[start] == b[end];
    }
    if (a[start] != b[end]) {
        return false;
    }

    return isReverse(a, b, start + 1, end - 1);
}

main()

public static void main(String[] args) {
    int[] a = {1, 2, 3, 4, 5, 6};
    int[] b = {6, 5, 4, 3, 2, 1};
    int[] c = {1, 2, 3, 4, 5, 6, 7};
    int[] d = {6, 5, 5, 3, 2, 1};
    System.out.println(isReverse(a, b)); // Should return true, returns false
    System.out.println(isReverse(a, c)); // Should return false, returns false
    System.out.println(isReverse(a, d)); // Should return false, returns false
}

输出

true
false
false

修复了初始鸿沟和征服版本的修复,

正如我之前所说的,问题位于基本情况中。而不是比较相同位置的元素a [start] == b [end]start> start等于end,它不会使感觉),我们需要调整end索引:

    if (start == end) {
        return a[start] == b[(b.length - 1) - end];
    }

这是需要应用于问题中列出的原始代码的唯一更改。

There's a couple of issues in your solution:

  • The base case has a logical flaw in it. The return value represents the result of comparison a[start] == b[end] when indices are equal. Which isn't the correct way to validate whether the one array is a reversed copy of another. Let's consider the two arrays a = [1, 2, 3] and b = [3, 2, 1]. We have to check whether a[0] == b[2], a[1] == b[1] and a[2] == b[0]. As you can see the case when indices are equal take place only once and only if the length is odd, if the length is even indices in all pair of elements will be different.

  • The second issue is the overall approach that you've taken. For this problem, we have to check all pairs of values. The divide and conquer approach is fruitless here because we can't reduce the amount of operations, in the worst case every pair of values needs to be compared.

I suggest addressing this problem with backtracking by simply moving the indices of both arrays by 1 at each method call, without utilizing the divide and conquer because we can't benefit from it.

First, let's fix the base case of recursion.

There are two cases when recursion should terminate: when values in the pair don't match and the last valid index has been reached.

The condition for the first case, when values that correspond to the current indices are not equal, will look that:

if (a[start] != b[end]) return false;

And the second part might be written like that:

if (start == a.length - 1) return a[start] == b[end];

or

if (start == a.length - 1) return true;

The meaning of both is almost the same - we've managed to compare all the pair of values (or the last pair is being compared). The first version is slightly better, it'll spare one method call.

In the recursive case, we are simply calling the method by passing the start incremented by 1 and the end decremented by 1.

private static boolean isReverse(int[] a, int[] b, int start, int end) {
    if (start == a.length - 1) {
        return a[start] == b[end];
    }
    if (a[start] != b[end]) {
        return false;
    }

    return isReverse(a, b, start + 1, end - 1);
}

main()

public static void main(String[] args) {
    int[] a = {1, 2, 3, 4, 5, 6};
    int[] b = {6, 5, 4, 3, 2, 1};
    int[] c = {1, 2, 3, 4, 5, 6, 7};
    int[] d = {6, 5, 5, 3, 2, 1};
    System.out.println(isReverse(a, b)); // Should return true, returns false
    System.out.println(isReverse(a, c)); // Should return false, returns false
    System.out.println(isReverse(a, d)); // Should return false, returns false
}

Output

true
false
false

Fix for the initial divide and conquer version

As I've said earlier, the problem resides in the base case. Instead of comparing the elements at the same position a[start] == b[end] (when start equals to end it will not make sense), we need to adjust the end index:

    if (start == end) {
        return a[start] == b[(b.length - 1) - end];
    }

That's the only change that needs to be applied to the original code listed in the question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文