【问题标题】:Finding index of array where min value occurs查找最小值出现的数组的索引
【发布时间】:2011-05-08 20:26:51
【问题描述】:

这个让我头晕目眩。就在我认为我明白了的时候,我意识到有些不对劲。我必须对这个作业使用递归。有什么提示吗?

/**
 * Uses recursion to find index of the shortest string.
 * Null strings are treated as infinitely long.
 * Implementation notes:
 * The base case if lo == hi.
 * Use safeStringLength(paths[xxx]) to determine the string length.
 * Invoke recursion to test the remaining paths (lo +1)
 */
static int findShortestString(String[] paths, int lo, int hi) {
    int min=lo;
    if (lo==hi)
        return min;
    if (safeStringLength(paths[lo]) < safeStringLength(paths[lo+1])){
        min=lo;
        return Math.min(min, findShortestString(paths, lo+1, hi));
    }
    else{
        min=lo+1;
        return Math.min(min, findShortestString(paths, lo+1, hi));
    }
}

【问题讨论】:

  • 这段代码是你做的吗?或者它是你必须使用的基础?
  • 我认为方法需要彻底改变;仅通过 hilo 连续不给我任何空间在返回的路上给出结果。
  • 是的,这就是为什么我说我卡住了..我不知道该怎么办
  • 我编辑它有一些进展,但它仍然关闭
  • 现在测试我的函数,如果我去掉所有的错别字,它会处理你评论中提到的所有任务。

标签: java arrays algorithm recursion


【解决方案1】:

为什么不直接获取每个元素的长度并对返回的长度进行排序以获得排序呢?像这样。

int[] intArray = {10, 17, 8, 99, 1}; // length of each element of string array
Arrays.sort(intArray);

【讨论】:

  • 它不是 int 数组,是 int 字符串数组
  • 您必须首先获取数组中每个元素的长度。然后将其存储在一个 int 数组中然后排序。
【解决方案2】:

我认为这里有一些东西:

static int findShortestString(String[] paths, int lo, int hi) 
{
    if (lo==hi)
        return lo;

    int ShortestIndexSoFar = findShortestString(paths, lo+1, hi);
    if(safeStringLength(paths[ShortestIndexSoFar]) < safeStringLength(paths[lo]))
        return ShortestIndexSoFar;
    else
        return lo;
}  

static int safeStringLength(String str)
{
    if(str == null)
        return Integer.MAX_VALUE;
    return str.length();
}

解释为什么会这样:
这是一个示例:

[0] ab
[1] abcd
[2] a
[3] abc
[4] ab

显然,索引 2 是最短的。
想想自下而上。从下往上阅读以下内容。
我听起来好像每个函数都在与链中它上面的函数交谈。
并且每一行都由传递的函数参数引导。

"[0] ab   (paths, 0, 4): return 2, coz he's shorter than me or anyone before us"
"[1] abcd (paths, 1, 4): return 2, coz he's shorter than me or anyone before us"
"[2] a    (paths, 2, 4): return 2, I'm shorter than anyone before me"
"[3] abc  (paths, 3, 4): return 4, coz he's shorter than me or anyone before us"
"[4] ab   (paths, 4, 4): return 4, I'm the shortest; I don't know any better"

因此,在代码中,您会看到确实发生了这种情况。
当我们定义ShortestIndexSoFar 时,每个函数都将知道它之外的所有路径中最短的路径。
紧随其后的是函数本身检查其索引的路径是否比以下所有路径中最短的路径更短。
继续向上滴下最短的那个,最后的那个人将返回最短的索引。

这有道理吗?

【讨论】:

  • 是的,这行得通..请解释一下这是如何工作的,我不明白
  • 一个问题:如果paths[lo] == null怎么办? safeStringLength(paths[lo]) 会抛出 NullPointerException,对吧?
  • @fprime;我添加了解释。
  • @Lajos 和@fprime;我给出的答案是完美世界中的最小解决方案。我把剩下的解决方案留给你 =) 这是不好的可能性:没有任何数据,或者传递相反的索引。
  • 如果有足够的输入字符串,这将炸毁堆栈。
【解决方案3】:

一个解决方案是这样的

public static final int findShortestString(final String[] arr, final int index, final int minIndex) {

    if(index >= arr.length - 1 ) {
        return minIndex;
    }

    if(-1 == safeStringLength(arr[index])) { 
        return index;
    }


    int currentMinIncex = minIndex;

    if(safeStringLength(arr[minIndex]) > safeStringLength(arr[index+1])){
        currentMinIncex = index + 1;
    }


    return findShortestString(arr, index + 1, currentMinIncex);

}



public static final int safeStringLength(final String string) {

    if( null == string) return -1;

    return string.length();

}

【讨论】:

    【解决方案4】:

    一个简单的解决方案:

    /**
         * Uses recursion to find index of the shortest string.
         * Null strings are treated as infinitely long.
         * Implementation notes:
         * The base case if lo == hi.
         * Use safeStringLength(paths[xxx]) to determine the string length.
         * Invoke recursion to test the remaining paths (lo +1)
         */
    static int findShortestString(String[] paths, int lo, int hi) {
        if (lo==hi)
            return lo;
        if (paths[lo] == null)
           return findShortestString(paths, lo+1, hi);
        int bestIndex = findShortestString(paths, lo+1, hi);
           if (safeStringLength[lo] < safeStringLength[bestIndex])
               return lo;
        return bestIndex;
    }
    

    【讨论】:

      【解决方案5】:

      根据运行findShortestString 的结果计算min 没有意义。开始此类问题的最佳方法是只考虑一个递归步骤,您可以通过考虑一个只有两个要比较的字符串的数组会发生什么来做到这一点。

      您要做的是检查第一个字符串的长度与第二个字符串的长度。然而,真正的技巧是你想通过递归调用函数来测试秒的长度。这很简单,但需要确定递归的最终情况。你成功地做到了,那是lo == hi。也就是说,当lo == hi 时,已知最短的字符串是lo(它是唯一已知的字符串!)。

      好的,回到只比较两个字符串。假设您知道要比较存储在 paths 中的两个字符串的长度,您可以执行以下操作(不使用递归):

      if(safeStringLength(paths[0]) < safeStringLength(paths[1])){
          return 0; // paths[0] is shorter
      }else{
          return 1; // paths[1] is shorter
      }
      

      但是你想要递归——并且在递归步骤中你需要以某种方式生成1paths[1]。我们已经想出了如何做到这一点,当lo == hi,我们返回lo。因此,递归步骤是“将当前已知的最低字符串长度与最知名索引的字符串长度进行比较”——等等,我们有一个函数!它是findShortestString。因此,我们可以将上面写的内容修改得更简洁一些,并添加基本情况得到:

      static int findShortestString(String[] paths, int lo, int hi) {
          // base case, no comparisons, the only known string is the shortest one
          if(lo == hi){
              return lo;
          }
      
          int bestIndex = findShortestString(paths, lo+1, hi);
          return safeStringLength(paths[lo]) < safeStringLength(paths[bestIndex]) ? 
              lo : bestIndex;
      }
      

      【讨论】:

        【解决方案6】:

        由于这是作业,这里有一个提示可以帮助您学习:

        findShortestString 方法的签名表明您应该使用二进制搜索。我为什么要这么说?为什么这样做是个好主意?所有其他解决方案都存在 Java 中的一个实际问题……那会是什么?

        对于 OP 以外的人...请不要泄露答案...例如通过更正你的答案!

        【讨论】:

        • 我们不是来管教人的 =) 他们提出问题,我们回答;如果他们愿意,他们应该自律。另一种可能性可能是 OP 已经无法按时开启此功能,但仍然有兴趣知道如何解决它。如果他只是想要一个提示,他就不会来SO。
        • @Beemer - 如果他想要的不仅仅是提示,他不应该来。我们不应该为人们做功课……不管他们寻求帮助的动机是什么。但是,很高兴看到您无论如何都没有给出答案:-)
        【解决方案7】:
        static int findShortestString(String[] paths, int lo, int hi)
        {  
          if (lo==hi)  
            return lo;  
          int ShortestIndexDown = findShortestString(paths, lo, (hi + lo)/2);
          int ShortestIndexUp = findShortestString(paths, (lo+hi)/2+1, hi);
          return SafeStringLength(paths[ShortestIndexDown]) < SafeStringLength(paths[ShortestIndexUp])?ShortestIndexDown:ShortestIndexUp;
        }
        
        static int safeStringLength(String str)
        {
          if(str == null)
            return Integer.MAX_VALUE;
          return str.length();
        }
        

        【讨论】:

        • 为什么是+(lo+hi)%2?你可以+1
        • @Axn - 考虑一下... :-)
        • @Stephen - 我想过。我还是不明白:(
        • "+(lo+hi)%2" 无效,改为"+1",虽然只是优化。这里的重点是最大堆栈深度将为 Log(N),因此堆栈溢出的可能性要小得多。
        猜你喜欢
        • 2017-08-13
        • 2017-11-05
        • 2016-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-25
        • 2021-11-06
        • 2013-11-02
        相关资源
        最近更新 更多