【问题标题】:Create sequence by choosing middle elements通过选择中间元素创建序列
【发布时间】:2018-07-10 04:49:58
【问题描述】:

我是新手程序员,一直停留在下面,

我想要一个输入数组的方法,比如说,

[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o]

并在输出中返回以下序列, (即找到中间并添加到数组中)

[h, d, l, b, j, f, n, c, i, e, k, g, m, a, o]

【问题讨论】:

  • 你尝试了什么?
  • 我尝试了几个递归函数,但无法得到我想要的
  • @SpectraTesting 是的,我认为你可以使用递归函数来做到这一点
  • @Spectra Testing - 更多的是根深蒂固的文化偏见,反对帮助人们解决明显的家庭作业问题。

标签: java arrays


【解决方案1】:

使用迭代加深方法:

public static void main(String[] args) {
    String[] input = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
        "l", "m", "n", "o"};
    String[] output = resequence(input);
    System.out.println(Arrays.asList(output));
}

private static String[] resequence(String[] input) {
    List<String> output = new ArrayList<>();
    for (int depth = 0; output.size() != input.length; ++depth) {
        iteration(input, 0, input.length, depth, 0, output);
    }
    return output.toArray(new String[output.size()]);
}

private static void iteration(String[] input, int min, int max,
        int target, int depth, List<String> output) {
    if (min < max) {
        int middle = (min+max)/2;
        if (target == depth) {
            output.add(input[middle]);
        } else {
            iteration(input, min, middle, target, depth+1, output);
            iteration(input, middle+1, max, target, depth+1, output);
        }
    }
}

但是这个输出是:

[h, d, l, b, f, j, n, a, c, e, g, i, k, m, o]

更新

使用广度优先方法:

static class Interval {
    private final int min;
    private final int max;

    Interval(int min, int max) {
        this.min = min;
        this.max = max;
    }
}

private static String[] resequence(String[] input) {
    List<String> output = new ArrayList<>();
    if (input.length > 0) {
        List<Interval> queue = new ArrayList<>();
        queue.add(new Interval(0, input.length));
        while (!queue.isEmpty()) {
            Interval ival = queue.remove(0);
            int middle = (ival.min+ival.max)/2;
            output.add(input[middle]);
            if (middle > ival.min) {
                queue.add(new Interval(ival.min, middle));
            }
            if (middle+1 < ival.max) {
                queue.add(new Interval(middle+1, ival.max));
            }
        }
    }
    return output.toArray(new String[output.size()]);
}

输出是:

[h, d, l, b, f, j, n, a, c, e, g, i, k, m, o]

【讨论】:

  • 非常感谢您的回答,对我很有帮助。
【解决方案2】:

假设 i/p 数组是 array1,其中包含 {a,b,c......m,n,o}。如果您希望输出数组存储中间元素,请创建另一个数组array2 并将array1 的中间元素存储到array2 中,然后从array1 中删除中间元素并继续上述过程直到array1 变为空。

您可以按照任何流程从array1 中删除元素

array = ArrayUtils.removeElement(array, element) //element is middle element of `array1` in your case

或者你可以通过使用for循环来做到这一点

for (int i = 0; i < array1.length; i++) {
// Delete Function
if (pos == i) { //pos is nothing but middle element
for (int j = i + 1; i < array1.length - 1; j++) {
array1[i] = array[j];
i++;
}
}
}

【讨论】:

  • 哦,他在做二叉树,我现在明白了。
【解决方案3】:

因此,您要做的就是玩“想一个介于 1 和 100 之间的数字”的游戏。在计算机科学中,我们称之为分治算法。在本科 Compsci 学位的所有内容中,它是最重要和最有用的内容之一。

那么这个游戏是如何运作的:

首先你选择 50。然后如果目标数字高于 50,你选择 75。然后如果它小于 75,你选择 62(或 63)。

这是一个二分搜索 - 因为在每一点你都有两个选项(嗯,四个真的 - 更高/更低/我们找到它/它不在树中)。

因此,我们可以在大约 7 次猜测(自然对数 (100))中从 100 中找到目标数,这对于较大的 N 值是巨大的速度提升。

所以你真正想做的就是接受这个:

[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o]

把它变成这样:

[                     h                     ]
[         d,                      l,        ]
[   b           f           j,          n,  ]
[a,    c,    e,    g,    i,    k,    m,    o]

然后您从“根”(位于图表顶部)向下走树

要递归执行此操作 - 使用如下伪算法:

 array pseudoRearrangeArray(arrayToRearrange) {
      return new array made up of:
          middle number
          +
          pseudoRearrangeArray(everything to the left of middle number)
          +
          pseudoRearrangeArray(everything to the right of middle number)
  }

当然这是错误的,因为它会输出 [ h, d, b, a, c, ...

看看你是否能找出原因,以及如何解决它。

【讨论】:

  • 感谢您的宝贵回答,实际上它正在返回预购序列,我想要平衡 BST 之类的序列:)
猜你喜欢
  • 2015-03-04
  • 1970-01-01
  • 1970-01-01
  • 2012-01-09
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 2014-07-08
相关资源
最近更新 更多