簡體   English   中英

遞歸stackoverflow Java

[英]Recursion stackoverflow Java

我需要計算右側小於數字 arr[i] 的數字數量。 我的問題是堆棧溢出大尺寸,我無法以任何方式解決它。 請告訴我如何重構我的代碼以避免錯誤 StackOverflow?

public class Smaller {
    public static int[] smaller(int[] unsorted) {
        int[] result = new int[unsorted.length];

        for (int i = 0; i < unsorted.length; i++) {
            result[i] = countSmaller(unsorted[i], 0, i + 1, unsorted);
        }

        return result;
    }

    private static int countSmaller(int currentNumber, int count, int index, int[] arr) {
        if (index >= arr.length) {
            return count;
        }

        return arr[index] < currentNumber
                ? countSmaller(currentNumber, count + 1, index + 1, arr)
                : countSmaller(currentNumber, count, index + 1, arr);
    }
}

我同意質疑遞歸是否是您最好的解決方案的評論,但如果這是一個要求,您可以通過將子問題切成兩半而不是逐個削減它們來避免堆棧溢出。 邏輯是剩余數據中的計數將是前半部分的計數加上剩余數據的后半部分的計數的總和。 這將堆棧增長從 O(n) 減少到 O(log n)。

很抱歉在 Python 中顯示此內容,但我沒有 Java 編譯器,我不想冒無法運行代碼的風險。 以下是訣竅,應該很容易翻譯:

def smaller(unsorted):
    result = []
    for i in range(len(unsorted)):
        result.append(countSmaller(unsorted[i], i+1, len(unsorted)-1, unsorted))
    return result

def countSmaller(threshold, start, end, unsorted):
    if start < end:
        mid = start + (end - start) // 2    # double slash is integer division
        count = countSmaller(threshold, start, mid, unsorted)
        count += countSmaller(threshold, mid+1, end, unsorted)
        return count
    elif start == end:
        if unsorted[start] < threshold:
            return 1
    return 0

data = [10, 9, 8, 11, 7, 6]
print(smaller(data))    # [4, 3, 2, 2, 1, 0]

print(smaller([]))      # []

print(smaller([42]))    # [0]

隨着 O(log n) 堆棧的增長,這應該能夠處理非常大的 arrays。

暫無
暫無

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

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