Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对数组排序的最小交换数_Javascript_Arrays - Fatal编程技术网

Javascript 对数组排序的最小交换数

Javascript 对数组排序的最小交换数,javascript,arrays,Javascript,Arrays,我需要这样做:假设我有一个数组: [3, 4, 1, 2] 我需要交换3和4,以及1和2,所以我的数组看起来像[4,3,2,1]。现在,我可以做sort()。在这里,我需要计算需要多少次迭代,以将初始数组更改为最终输出。例如: // I can sort one pair per iteration let array = [3, 4, 1, 2, 5] let counter = 0; //swap 3 and 4 counter++; // swap 1 and 2 counter++

我需要这样做:假设我有一个数组:

 [3, 4, 1, 2]
我需要交换3和4,以及1和2,所以我的数组看起来像
[4,3,2,1]
。现在,我可以做
sort()
。在这里,我需要计算需要多少次迭代,以将初始数组更改为最终输出。例如:

// I can sort one pair per iteration
let array = [3, 4, 1, 2, 5]
let counter = 0;

//swap 3 and 4
counter++;
// swap 1 and 2
counter++;
// 5 goes to first place
counter++

// now counter = 3 <-- what I need
//我可以在每次迭代中对一对进行排序
让数组=[3,4,1,2,5]
设计数器=0;
//互换3和4
计数器++;
//互换1和2
计数器++;
//第五名排在第一位
柜台++

//现在,counter=3我假设有两个原因需要度量排序所需的迭代次数。因此,我将提供一些理论(如果数学过于密集,不要担心),然后提供一些实际应用

有许多排序算法,其中一些算法根据您正在排序的项的数量有一个可预测的迭代次数,一些算法只是根据要排序的项的顺序以及您如何选择称为轴心的项进行绘制。因此,如果优化对您非常重要,那么您需要为排序算法选择正确的算法。否则,使用通用算法

以下是用于学习的最流行的排序算法,每种算法都有最少、最差和平均运行情况。如果这不仅仅是一个理论/学习练习,那么Heapsort、基数和二进制排序就值得一看

快速分类 最坏情况:Θ(n2)

最佳案例:Θ(n lg n)

平均情况:Θ(n lg n)

合并排序 最坏情况:Θ(n lg n)

最佳案例:Θ(n lg n)

平均情况:Θ(n lg n)

(注意它们都是一样的)

插入排序 最坏情况:Θ(n2)

最佳案例:Θ(n)

平均病例:Θ(n2)

(请注意,其最坏情况和平均情况相同,但其最佳情况是任何算法中的最佳情况)

选择排序 最坏情况:Θ(n2)

最佳案例:Θ(n2)

平均病例:Θ(n2)

(注意它们都是一样的,就像合并排序一样)

您可以很容易地将迭代器变量添加到这些示例中的任何一个,以计算它们进行的交换的数量,并使用它们来查看哪些算法在哪种情况下工作得最好

如果项目很有可能已经进行了很好的排序,那么插入排序是您的最佳选择。如果您完全不知道,在四种基本排序算法中,快速排序是您的最佳选择

function minimumSwaps(arr) {

   var counter = 0;

   for (var i = arr.length; i > 0; i--) {
      var minval = Math.min(...arr); console.log("before", arr);
      var minIndex = arr.indexOf(minval);
      if (minval != = arr[0]) {
         var temp = arr[0];
         arr[0] = arr[minIndex];
         arr[minIndex] = temp; console.log("after", arr);
         arr.splice(0, 1);
         counter++;
      }
      else {
         arr.splice(0, 1); console.log("in else case")
      }

   } return counter;
}
这是我如何调用交换函数的:

最小互换([3,7,6,9,1,8,4,10,2,5])

它与选择排序一起工作。逻辑如下:

  • 循环遍历数组长度
  • 如果第0个索引没有找到最小值,则查找数组中的最小元素,然后与数组中的第一个元素交换
  • 现在移除第一个元素
  • 如果没有步骤2,则移除第一个元素(已经存在的最小值)
  • 交换值时增加计数器
  • 返回for循环后的计数器值
  • 它适用于所有价值观


    但是,由于50000左右的值超时,该解决方案失败。

    此解决方案简单快速

    function minimumSwaps(arr) {
    
        let minSwaps = 0;
    
        for (let i = 0; i < arr.length; i++) {
            // at this position what is the right number to be here
            // for example at position 0 should be 1
            // add 1 to i if array starts with 1 (1->n)
            const right = i+1;
            // is current position does not have the right number
            if (arr[i] !== right) {
                // find the index of the right number in the array
                // only look from the current position up passing i to indexOf
                const rightIdx = arr.indexOf(right, i);
                // replace the other position with this position value
                arr[rightIdx] = arr[i];
                // replace this position with the right number
                arr[i] = right;
                // increment the swap count since a swap was done
                ++minSwaps;
            }
        }
    
        return minSwaps;
    }
    
    功能最小交换(arr){
    设minSwaps=0;
    for(设i=0;in)
    const right=i+1;
    //当前位置是否没有正确的编号
    if(arr[i]!==右){
    //在数组中找到正确数字的索引
    //仅从当前位置向上看,通过i到indexOf
    常数rightIdx=arr.indexOf(右,i);
    //用该位置值替换另一个位置
    arr[rightIdx]=arr[i];
    //用正确的编号替换此位置
    arr[i]=对;
    //自交换完成后增加交换计数
    ++明斯瓦普斯;
    }
    }
    返回明斯瓦普;
    }
    
    这是迄今为止我尝试过的最优化的代码,而且该代码也被认为是最优的 答复如下:

    功能最小交换(arr){
    var arrLength=arr.length;
    //创建两个新阵列
    //分别记录一个值和一个键
    //第二个保持访问节点计数(默认设置为false为all)
    var newArr=[];
    var newarr=[];
    for(设i=0;i0){
    swp+=(循环>1)?循环-1:循环;
    } 
    }
    返回swp;
    }
    


    这是我的解决方案,但它会超时3个输入非常大的测试用例。对于较小的输入,它工作并且不会因超时而终止

    function minimumSwaps(arr) {
      let swaps = 0;
      for (let i = 0; i < arr.length; i++) {
        if (arr[i] === i + 1) continue;
        arr.splice(i, 1, arr.splice(arr.indexOf(i + 1), 1, arr[i])[0]); //swap 
        swaps++;
      }
      return swaps;
    }
    
    
    功能最小交换(arr){
    设互换=0;
    for(设i=0;i

    我正在学习如何使它更有效,欢迎任何帮助。

    除非你已经对计算机科学或真正的数学知识有点熟悉,否则这个问题的解决方案不是很直观,但这一切都归结于反演的数量和
    function minimumSwaps(arr) {
        var arrLength = arr.length;
    
        // create two new Arrays 
        // one record value and key separately
        // second to keep visited node count (default set false to all)
    
        var newArr = [];
        var newArrVisited = [];
        for (let i = 0; i < arrLength; i++) {
            newArr[i]= [];
            newArr[i].value = arr[i];
            newArr[i].key = i;
            newArrVisited[i] = false;
        }
    
        // sort new array by value
    
        newArr.sort(function (a, b) {
            return a.value - b.value;
        })
    
        var swp = 0;
        for (let i = 0; i < arrLength; i++) {
    
            // check if already visited or swapped
            if (newArr[i].key == i || newArrVisited[i]) {
                continue;
            }
    
            var cycle = 0;
            var j = i;
            while (!newArrVisited[j]) {
    
                // mark as visited
                newArrVisited[j] = true;
                j = newArr[j].key; //assign next key
                cycle++;
            }
            if (cycle > 0) {
                swp += (cycle > 1) ? cycle - 1 : cycle;
            } 
    
        }
        return swp;
    }
    
    function minimumSwaps(arr) {
      let swaps = 0;
      for (let i = 0; i < arr.length; i++) {
        if (arr[i] === i + 1) continue;
        arr.splice(i, 1, arr.splice(arr.indexOf(i + 1), 1, arr[i])[0]); //swap 
        swaps++;
      }
      return swaps;
    }
    
    
    export const minimumSwaps = (arr) => {
    
      //This function returns the lowest value
      //from the provided array.
      //If one subtracts this value the from
      //any value in the array it should equal
      //that value's index.
      const shift = (function findLowest(arr){
          let lowest=arr[0];
          arr.forEach((val,i)=>{
              if(val<lowest){
                  lowest=val;
              }
          })
          return lowest;
      })(arr);
    
      //Declare a counter variable
      //to keep track of the swaps.
      let swaps = 0;
    
      //This function returns an array equal
      //in size to the original array provided. 
      //However, this array is composed of 
      //boolean values with a value of false.
      const visited = (function boolArray(n){
          const arr=[];
          for(let i = 0; i<n;i++){
              arr.push(false);
          }
          return arr;
        })(arr.length);
    
      //Iterate through each element of the
      //of the provided array.
      arr.forEach((val, i) => {
    
        //If the current value being assessed minus
        //the lowest value in the original array
        //is not equal to the current loop index,
        //or, if the corresponding index in
        //the visited array is equal to true,
        //then the value is already sorted 
        if (val - shift === i || visited[i]) return;
    
        //Declare a counter variable to record
        //cycle length.
        let cycleLength = 0;
    
        //Declare a variable for to use for the 
        //while loop below, one should start with
        //the current loop index
        let x = i;
    
        //While the corresponding value in the
        //corresponding index in the visited array
        //is equal to false, then we 
        while (!visited[x]) {
    
          //Set the value of the current
          //corresponding index to true
          visited[x] = true;
    
          //Reset the x iteration variable to
          //the next potential value in the cycle  
          x = arr[x] - shift;
    
          //Add one to the cycle length variable
          cycleLength++;
        };
    
        //Add the minimum number of swaps to
        //the swaps counter variable, which
        //is equal to the cycle length minus one
        swaps += cycleLength - 1;
    
      });
    
      return swaps
    
    }
    
    //this function calls the mainSwaps function..
    function minimumSwaps(arr){
           let swaps = 0;
    
            for (var i = 0; i < arr.length; i++){
                var current = arr[i];
                var targetIndex = i + 1;
                if (current != targetIndex){
                    swaps += mainSwaps(arr, i);
                }
            }
    
            return swaps;
    
    }
    
    //this function is called by the minimumSwaps function
    function mainSwaps(arr, index){
        let swapCount = 0;
        let currentElement = arr[index];
        let targetIndex = currentElement - 1;
        let targetElement = arr[currentElement - 1];
    
        while (currentElement != targetElement){
            //swap the elements
            arr[index] = targetElement;
            arr[currentElement - 1] = currentElement;
    
            //increase the swapcount 
            swapCount++;
    
            //store the currentElement, targetElement with their new values..
            currentElement = arr[index];
            targetElement = arr[currentElement - 1];
        }
    
        return swapCount;
    }
    
    var myarray = [2,3,4,1,5];
    var result = console.log(minimumSwaps(myarray));
    
    //You are given an unordered array consisting of consecutive integers  [1, 2, 3, ..., n] without any duplicates.
    //still not the best
    
    function minimumSwaps(arr) {
         let count = 0;
        for(let i =0; i< arr.length; i++){
            if(arr[i]!=i+1){
                let temp = arr[i];
                arr[arr.indexOf(i+1)] =temp;
                arr[i] = i+1;
                count =count+1;
            }
        }
        return count;
    }