簡體   English   中英

如何在線性時間內按絕對值重新排序排序數組?

[英]How can I re-sort a sorted array by absolute values, in linear time?

您將獲得一個包含負值和正值的排序數組。 使用負數絕對值的數組。 你的復雜度應該是 O(n)

樣本輸入

[-8, -5, -3, -1, 3, 6, 9]

預計 Output

[ -1, -3, 3, -5, 6, -8, 9 ]

到目前為止我已經這樣做了,但是 output 是不正確的。

function sortMe(input) {
   var newArr = [];
   for (var i = 0; i < input.length; i++) {
     var value = Math.abs(input[i]);
     newArr.push(value);
   }
   var c = newArr.sort()
}

它給了 output

[ 1, 3, 3, 5, 6, 8, 9 ]
  1. 將數組分成兩半,一個是負數,另一半是正數。

  2. 反轉負數數組。

  3. 然后,使用兩個數組的絕對值運行合並算法

總體運行時復雜度仍然是 O(n)。


function sortMe(sortedArray) {

  var idx = -1, negs, pos, result = [], nIdx = 0, pIdx = 0;

  if (sortedArray.length === 0)
    return result;

  // Find the index where positive elements begin
  while (idx < sortedArray.length && sortedArray[++idx] < 0);

  // Get elements till the index and reverse the array
  negs = sortedArray.slice(0, idx).reverse();

  // Get elements from the index till the end
  pos = sortedArray.slice(idx);

  // Merging algorithm implementation which merges `negs` and `pos`
  while (nIdx < negs.length || pIdx < pos.length)
  {
    if (nIdx < negs.length && pIdx < pos.length)
    {
      if (Math.abs(negs[nIdx]) <= pos[pIdx])
        result.push(negs[nIdx++]);
      else
        result.push(pos[pIdx++]);
    }
    else if (nIdx < negs.length)
      result.push(negs[nIdx++]);
    else
      result.push(pos[pIdx++]);
  }

  return result;
}

console.log(sortMe([-8, -5, -3, -1, 3, 6, 9]));
// [ -1, -3, 3, -5, 6, -8, 9 ]

 function sortMe(sortedArray) { var idx = -1, negs, pos, result = [], nIdx = 0, pIdx = 0; if (sortedArray.length === 0) return result; // Find the index where positive elements begin while (idx < sortedArray.length && sortedArray[++idx] < 0); // Get elements till the index and reverse the array negs = sortedArray.slice(0, idx).reverse(); // Get elements from the index till the end pos = sortedArray.slice(idx); // Merging algorithm implementation which merges `negs` and `pos` while (nIdx < negs.length || pIdx < pos.length) { if (nIdx < negs.length && pIdx < pos.length) { if (Math.abs(negs[nIdx]) <= pos[pIdx]) result.push(negs[nIdx++]); else result.push(pos[pIdx++]); } else if (nIdx < negs.length) result.push(negs[nIdx++]); else result.push(pos[pIdx++]); } return result; } function getElement(id) { return document.getElementById(id); } function sorter() { var data = getElement("numbers").value.split(" ").map(Number); getElement("result").innerHTML = "[" + sortMe(data).join(", ") + "]"; }
 <input id="numbers" value="-8 -5 -3 -1 3 6 9" /> <input type="button" onclick="sorter()" value="Click here to Sort" /> <pre id="result" />

int[] arr = new int[] { -8, -5, -3, -1, 3, 6, 9 }; for(int i = 0; i < arr.length; i++) { int pos = 0; for (int j = 0; j < arr.length; j++) { if (Math.abs(arr[pos]) > Math.abs(arr[j])) { int temp; temp = arr[pos]; arr[pos] = arr[j]; arr[j] = temp; pos++; } } }

可以通過考慮3種情況來完成:

一種。 所有正數:保持數組不變

所有負數:反轉數組

C。 正數和負數:找到輸入數組中的最后一個負數,然后使用左右進行比較。

import java.util.Arrays;

public class SortAbsoluteValue {
    // all positive; all negative; postive & negative
    public static void main(String[] args) {
        int[] num = new int[] { -8, -5, -3, -1, 3, 6, 9 };
        int[] result = sortAbsolute(num);

        for (int i = 0; i < num.length; i++) {
            System.out.println(result[i]);
        }
    }

    private static int[] sortAbsolute(int[] num) {
        int size = num.length;
        // all positive : leave as is
        if (num[0] >= 0)
            return num;
        // all negative : reverse array
        if (num[size-1] < 0) {
            int[] temp = Arrays.copyOf(num, num.length);
            Arrays.sort(temp);
            return temp;
        }
        int[] result = new int[size];

        int i = 0;
        for (i = 0; i < size - 1; i++) {
            if (num[i] < 0 && num[i + 1] >= 0) {
                break;
            }
        }

        int left = i - 1;
        int right = i + 1;
        result[0] = num[i];
        int k = 0;
        while (left >= 0 && right < size) {
            if (Math.abs(num[left]) < num[right]) {
                result[++k] = num[left];
                left--;
            } else {
                result[++k] = num[right];
                right++;
            }
        }
        // remaining left elements, if any
        while(left>=0) {
            result[++k] = num[left--];
        }
        // remaining right elements, if any
        while(right<size) {
            result[++k] = num[right++];
        }
        return result;
    }
}

@thefourtheye,您的解決方案非常好,但它不能糾正數字(正負數字)混合的過程編號序列。 您可以使用下一個序列檢查您的解決方案,例如:[-2 -5 3 8 -10] 它會給您錯誤的結果:[3, -5, -2, 8, -10]。

這是因為:

1)您依賴負數和正數應按排序順序排列。

2) 找出正數和負數的索引,盡管它們可能不一致。

我已經更正了您的代碼,現在它可以處理任何混合的正/負數序列,並按絕對值對它們進行正確排序。 代碼如下:

function sortArrayByAbsValues(sortedArray) {

                var negs = [], pos = [], result = [], nIdx = 0, pIdx = 0;

                if (sortedArray.length === 0)
                    return result;

                //prepare negative/positive number sequences.
                for (var i = 0; i < sortedArray.length; i++) {
                    var value = sortedArray[i];
                    if (value < 0) {
                        negs.push(value);
                    } else {
                        pos.push(value);
                    }
                }
                // sort positive/negative numbers
                pos = pos.sort();
                negs = negs.sort();

                // Merging algorithm implementation which merges `negs` and `pos`
                while (nIdx < negs.length || pIdx < pos.length) {
                    if (nIdx < negs.length && pIdx < pos.length) {
                        if (Math.abs(negs[nIdx]) <= pos[pIdx])
                            result.push(negs[nIdx++]);
                        else
                            result.push(pos[pIdx++]);
                    }
                    else if (nIdx < negs.length)
                        result.push(negs[nIdx++]);
                    else
                        result.push(pos[pIdx++]);
                }

                return result;
            }
inputArray.sort(function(a,b) {
    return Math.abs(a) - Math.abs(b);
});

可能不是 O(n) 但對我來說效果很好

您可以使用冒泡排序簡單地實現這一點

 var array= new Array(2,-2,3,5,-3,1);

 function absoluteSortin(array){

    var inputArray= array.slice(0);
    var temp;

    for(var i=0;i< inputArray.length;i++){
        for(j=i+1; j<inputArray.length;j++){
            if(Math.abs(inputArray[i]) > Math.abs(inputArray[j])){
                temp= inputArray[j];
                inputArray[j] = inputArray[i];
                inputArray[i] = temp;
            }
        }
    }
   return inputArray;

 }
 absoluteSortin(array);
<?php
$a = array(-2,-3,0,5,4,1,6,9,7,-9,-1,3);
for($i=0;$i<count($a)-1;$i++) {
    for($j=0;$j<count($a)-1;$j++){
        $data1=abs($a[$j]);
        $data2=abs($a[$j+1]);
        if($data1>$data2) {
            $temp = $a[$j];
            $a[$j] = $a[$j+1];
            $a[$j+1] = $temp;
        }
    }
}
echo "<pre>";
print_R($a);
?>

這是Python中的代碼

    def sorted_array(list1):
        list_negative=[]
        list_positive=[]

        for i in list1:
        if i<0:
            list_negative.append(i)
        else:
            list_positive.append(i)

        list_negative.reverse()    

        for i in list_negative:
            for j in range(0, len(list_positive)):
                if abs(i)<=list_positive[j]:
                    list_positive.insert(j,i)
                    break
        print(list_positive)    
    list1=[-8,-5,-3,-1,3,6,9,-4]    
    sorted_array(list1)

兩個指針的方法。

void resort(vector<int> &a){

   int par ; // partition index (when +ve elements starts)

   // lets find where positive elements starts
   for(int i = 0; i < a.size(); i++){
      if(a[i] >= 0) {
         par = i;
         break;
      }
   }

  int l = par-1; // left of par
  int r = par;   // right side

  vector<int> b; // extra array for answer

 
  // compare left and right side element
  // if any of them is lesser push that element in extra array i.e 'b'
  while(l >= 0 and r < a.size()) {

     if(abs(a[l]) > a[r]) {
        b.push_back(a[r]);
        r++;
     }
     else if(abs(a[l]) < a[r]){
        b.push_back(a[l]);
        l--;
     }
     else{
        b.push_back(a[l]);
        l--;
     }
  }

 // push remaing element from both side
 // like merge sort

  while(l >= 0) {
    b.push_back(a[l]);
    l--;
  }
  while(r < a.size()) {
     b.push_back(a[r]);
     r++;
  }

  // print modified answer
  for(auto x:b) {
     cout<<x<<" ";
  }
}

時間完成在)

空間組合在)

您可以使用 Python 中的一行

nums = [-8, -5, -3, -1, 3, 6, 9]

print(sorted(nums,key=abs))

output 將是

[-1, -3, 3, -5, 6, -8, 9]

這是一個快速的解決方案

  • 拆分列表分為兩部分,第一部分為負數,第二個列表將包含正數

  • 應用合並算法來合並 c#- 中的兩個列表示例。

     List<int> neg = arr.Where(x => x < 0).Reverse().ToList(); List<int> pos = arr.Where(x => x > 0).ToList(); var res=merge(neg,pos); private static List<int> merge(List<int> left, List<int> right) { List<int> result = new List<int>(); while (left.Count > 0 || right.Count > 0) { if (left.Count > 0 && right.Count > 0) { if (Math.Abs(left.First()) <= right.First()) { result.Add(left.First()); left.Remove(left.First()); } else { result.Add(right.First()); right.Remove(right.First()); } } else if (left.Count > 0) { result.Add(left.First()); left.Remove(left.First()); } else if (right.Count > 0) { result.Add(right.First()); right.Remove(right.First()); } } return result; }

暫無
暫無

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

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