對陣列中的數字 1 和 2 進行排序,使得數字 1、2 分別位於前、後部分

小珥_Boy發表於2019-03-11

問題描述:假設某個陣列中只有數字 1 和 2,進行排序,使得數字 1 位於陣列前部分,數字 2 位於後部分。

這道演算法題其實不是很難,使用各種排序演算法應該都能解出,但是若要考慮效能問題,那就得選擇一種演算法複雜度最低的解法。這裡我使用雙指標的方法來解答該題,時間複雜度為 O(n)

  1. 解法步驟

(1)設定一個頭指標、一個尾指標,頭指標首先指向陣列的第一個元素(索引為 0),而尾指標則指向陣列的最後一個元素(索引為 len - 1,假定陣列的長度為 len);

(2)然後比較這兩個一前一後元素的大小;

  • 若兩值不相等,則較小的 1 放在前面,較大的 2 放在後面,頭指標往後移動一步,尾指標向前移動一步;
  • 若兩值相等且都等於 1,則頭指標往後移動一步,尾指標不移動;
  • 若兩值相等且都等於 2,則尾指標往前移動一步,頭指標不移動;

(3)接著再次比較頭、尾指標指向元素的大小,決定是否交換值以及移動指標;

(4)依照以上步驟進行指標移動、元素大小比較,便可使得數字 1 位於陣列前部分,數字 2 位於陣列後部分。

  1. 注意點:上面迴圈進行操作的條件是頭指標索引值小於尾指標索引值。

  2. 書寫的程式碼如下:

function sortOneTwoInArr (arr) {
  var len = arr.length;
  var head = 0;
  var tail = len - 1;
  /* 遍歷陣列,對 1 和 2 進行排序 */
  while (head < tail) {
    // 若頭、尾指標指向的元素大小相等則只移
    // 動一個指標,否則同時移動兩個指標
    if (arr[head] === arr[tail]) {
      if (arr[head] === 1) {
        head++;
      } else if (arr[head] === 2) {
        tail--;
      }
    } else {
      if (arr[head] > arr[tail]) {
        [arr[head], arr[tail]] = [arr[tail], arr[head]];
      }
      head++;
      tail--;
    }
  }
  return arr;
}

/* 測試用例 */
var arr1 = [];
var arr2 = [1];
var arr3 = [2];
var arr4 = [1, 2, 1, 2];
var arr5 = [1, 1, 2, 2];
var arr6 = [1, 2, 2, 1, 1];
var arr7 = [2, 2, 1, 1, 2];
console.log(sortOneTwoInArr(arr6));         // [1, 1, 1, 2, 2]
複製程式碼

相關文章