【问题标题】:Longest Snake Sequence最长的蛇序列
【发布时间】:2015-06-11 18:25:57
【问题描述】:

问题:以空格分隔的一组数字作为输入传递。程序必须打印数字中存在的最大蛇序列。蛇序列由相邻的数字组成,因此对于每个数字,右侧或左侧的数字是其值的 +1 或 -1。如果可能有多个最大长度的蛇序列,则打印以自然输入顺序出现的蛇序列。

输入/输出示例 1:

输入

5 6 7 9 8 8

输出

5 6 7 8 9 8

8 9 8 7 6 5

示例输入/输出 2:

输入

9 8 7 5 3 0 1 -2 -3 1 2

输出

3 2 1 0 1

void doPermute(int[] in, StringBuffer out, boolean[] used, int length, int level, StringBuffer max) {
    if (level == length) {
        int count = 0;
        for (int i = 1; i < out.length(); i++) {
            if (Math.abs(Character.getNumericValue(out.charAt(i)) - Character.getNumericValue(out.charAt(i - 1))) != 1) {
                //System.out.println(Character.getNumericValue(i) - Character.getNumericValue(i - 1) + "  " + i + "   yes");
                count++;
                break;
            }
        }
        if (count == 0) {
            max.append(out + " ");

        }

        return;
    }
    for (int i = 0; i < length; ++i) {
        if (used[i]) {
            continue;
        }
        out.append(in[i]);
        used[i] = true;
        doPermute(in, out, used, length, level + 1, max);
        used[i] = false;
        out.setLength(out.length() - 1);
    }
}

当我使用 StringBuffer 时,我的代码通过了包含正值的测试用例(第一个测试用例),但在包含负值的测试用例中失败了(第二个测试用例)。

更新:- 我将 stringbuffer 替换为 Integer[] 并进行了一些更改。它适用于长度为 8 或 9 的较小输入。如何使其快速用于长度为 13 到 15 的较大输入?

【问题讨论】:

  • 它是如何失败的?你得到了什么输出?你的问题是什么?您是否已努力调试程序并缩小问题所在?
  • 使用字符串缓冲区它需要 -2 作为 - 和 2
  • 你能说得更详细些吗?我剩下的问题呢?
  • @tnw 在测试用例 1 中,都是正值,所以它置换为 567889,然后 567898 等等,而在负值的情况下如 5 6 7 8 8 -9,它置换为 5 6 7 8 8 - 9。所以它认为'-'符号是一个字符而不是'-9'。
  • 好吧,doPermute 中的 for 循环每次从 StringBuffer 获取一个字符并对其进行处理。是什么让您认为它应该-9 视为-9?如果要将内容解析为数字,则需要这样做。

标签: java arrays recursion sequence permutation


【解决方案1】:

您是否尝试过使用整数数组来完成这个过程?

Scanner sc = new Scanner(System.in);
String s = sc.nextLine(); //The numbers entered in string format separated by spaces
String ss = s.split(" "); //Numbers separated by space will be put as individual numbers in a String array but each number is still in string format
int l = ss.length, i = 0;
int[] n = new int[l]; //The integer array which will store the values
for(i = 0; i < l; i++)
{
    n[i] = Integer.parseInt(ss[i]);  //Has integers now instead of string numbers
}

可能会创建一些额外的数组,但重复调用Character.getNumericValue() 函数也会降低效率。也可能解决您的 StringBuffer 问题。

但无论如何,SkillRack 很烦人。

【讨论】:

  • 我试过了,但较大的值需要很长时间。有什么可以让它快点的吗?
【解决方案2】:

您的比较没有找到负值的相邻数字。 例如:Abs(-2) - (-3) = 5-2-3 应该是相邻的。 行。我看到你正在解析 - 和数字分开。 鉴于蛇序列的要求,“5 6 7 9 8 8”的最长蛇序列是“5 6 7”。上面列出的输出不对应于定义:“相邻的数字,使得对于每个数字,右侧或左侧的数字是其值的 +1 或 -1”。 “5 6 7 8 9 8”如何满足“5 6 7 9 8 8”蛇序列的定义?对不起,我帮不上忙。 您可能希望将代码解析为整数,将最长的序列存储在映射中。

@Test
public void testSnake(){
    String t2 = "9 8 7 5 3 0 1 -2 -3 1 2";
    List<String> numsStr = Arrays.asList(t2.split(" "));
    List<Integer> nums = new ArrayList();
    HashMap<Integer,List<Integer> > numMap = new HashMap();

    numsStr.forEach((s) -> {
        Integer val = Integer.decode(s);
        nums.add(val);
    });

    nums.forEach((num) -> {
        System.out.println("num: " + num);
        // track longest sequence, store in numMap
    });
    // Print numMap
}

【讨论】:

  • 问题在于字符串缓冲区方法,因为在执行时它将负值作为单独的字符.ex(-2 as - & 2)。
  • "567898" for "567988" 是正确的,因为它们是数字之间的 +1 或 -1 差异。
  • 我认为相邻数字的要求意味着它们必须在输入流中相邻。按照它们的自然顺序。
  • 我做了一些改动,效果很好,但对于更大的价值,它花了很多时间。有什么让它更快的想法吗?
  • 摆脱递归。你有一个 O(n^2) 递归算法。您可以在不递归的情况下以 O(n) 性能完成解决方案。我正在旅行,目前没有我的电脑,所以无法发布代码。您可以遍历输入,将每个项目放在 TreeMap 中,跟踪您是否使用了具有 numItems 值的链中的项目,对于每个项目,查看地图并查看是否有值左右,将最长链存储在 List 中,在末尾打印列表列表。简而言之,这就是我要做的。
猜你喜欢
  • 2017-02-25
  • 1970-01-01
  • 2016-05-16
  • 2016-02-04
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多