簡體   English   中英

使用 typescript 計算數組中的反轉

[英]Counting inversions in an array with typescript

幾個小時以來,我一直在努力解決這個錯誤,但似乎找不到錯誤在哪里。

我正在嘗試計算給定數組中的反轉,並且我的所有測試都通過了,除非將此數組用作輸入 [6、1、2、5、4、3]。

邏輯如下; 給定數組 A[1...n],對於每個 i < j,找到所有反轉對,使得 A[i] > A[j]

我收到的這個數組的數字是 14 次反轉,正確答案是 8。

到目前為止的代碼是這樣的

function mergeCount(left: number[], right: number[]): number {
  let count = 0;
  let leftCounter = 0;
  let rightCounter = 0;

  while (leftCounter < left.length && rightCounter < right.length) {
    if (left[leftCounter] < right[rightCounter]) {
      leftCounter += 1;
    } else {
      count += left.length - leftCounter;
      rightCounter += 1;
    }
  }

  return count;
}

function countInversions(input: number[]): number {
  if (input.length < 2) return 0;

  const middle = Math.floor(input.length / 2);

  const left = input.slice(0, middle);
  const right = input.slice(middle);

  return countInversions(left) + countInversions(right) + mergeCount(left, right);
}

知道我缺少什么或我的代碼有什么問題嗎?

編輯:

所以問題是我在拆分 arrays 時沒有對它們進行排序,我只是在更新計數器。 我想出的工作解決方案如下

function mergeCount(left: number[], right: number[]): { output: number[]; count: number } {
  let count = 0;
  let leftCounter = 0;
  let rightCounter = 0;
  const output: number[] = [];

  while (leftCounter < left.length && rightCounter < right.length) {
    if (left[leftCounter] < right[rightCounter]) {
      output.push(left[leftCounter]);
      leftCounter += 1;
    } else {
      output.push(right[rightCounter]);
      count += left.length - leftCounter;
      rightCounter += 1;
    }
  }

  return {
    output: output.concat(left.slice(leftCounter)).concat(right.slice(rightCounter)),
    count,
  };
}

function countInversions(input: number[]): { output: number[]; count: number } {
  if (input.length < 2) return { output: input, count: 0 };

  const middle = Math.floor(input.length / 2);

  const { output: left, count: a } = countInversions(input.slice(0, middle));
  const { output: right, count: b } = countInversions(input.slice(middle));
  const { output, count: c } = mergeCount(left, right);

  return { output, count: a + b + c };
}

您鏈接到的 Python 代碼也對數組進行排序 - 您沒有。 這可能會導致錯誤的答案,因為基於合並排序的倒數計數算法要求您在處理數組時也對數組進行排序(否則,它使用的快捷方式將無效)。

只需在您的mergeCount right left ,也返回它,它應該可以工作。

下面突出顯示的 Python 是您的代碼中缺少的內容:

 while i < left_len and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i]) # this
            i += 1
        else:
            result.append(right[j]) # and this
            count += left_len - i
            j += 1

要提供有關合並排序反轉計數思想的更多背景信息:

在歸並排序中,我們有兩個已排序的一半H1H2H1已排序, H2已排序。 我們有一個合並 function 將這兩個有效地合並到一個大的排序數組中。

現在,這(嗯,應該)在 OP 的 while 循環中完成。 請注意,如果,使用他的符號:

left[leftCounter] > right[rightCounter]

(他的 else 條件),然后因為left已排序,所以leftCounter之后的所有元素也將大於right[rightCounter] ,所以我們有left.length - leftCounter反轉 - 允許我們一次計算多個 1。

當然,這僅在您讓 mergesort 做它的事情並實際對數組進行排序時才成立。

當前的實現看起來相當復雜。 我認為它可能更簡單(和准確)。

迭代外循環中的所有元素。 我們稱索引為i 在內部循環中,遍歷所有大於i的元素並將它們與外部索引元素進行比較。

function countInversions(input: number[]): number {
    let count = 0;
    for (let i = 0; i < input.length; i++) {
        for (const num of input.slice(i + 1)) {
            if (input[i] > num) {
                count++;
            }
        }
    }
    return count;
}

暫無
暫無

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

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