簡體   English   中英

查找出現最小值的數組的索引

[英]Finding index of array where min value occurs

這使我旋轉。 就在我覺得自己明白了的時候,我意識到有些不對勁。 我必須為此任務使用遞歸。 有什么提示嗎?

/**
 * 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));
    }
}

我認為這里有一些東西:

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 ,這是每個函數將知道其以外所有路徑中最短路徑的地方。
緊隨其后的是函數本身檢查其索引的路徑是否短於下面所有索引中最短的路徑。
繼續向上滴最短的索引,最后一個家伙將返回最短的索引。

那講得通?

由於這是家庭作業,因此以下提示可幫助您學習:

findShortestString方法的簽名表明您應該使用二進制搜索。 我為什么要這樣說呢? 為什么這樣做是個好主意? 所有其他解決方案都存在Java的實際問題……那是什么?

對於OP以外的其他人...請不要給出答案...例如,通過更正您的答案!

為什么不僅僅獲取每個元素的長度並對返回的長度進行排序以獲得順序呢? 像這樣。

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

一種解決方案將是這樣

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();

}

一個簡單的解決方案:

/**
     * 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;
}

在運行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;
}
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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM