Ikkita massivni birlashtirish va yakuniy tartibini tartiblashtirish

Suhbatdoshimga quyidagi savol berildi. Menga ikkita array berildi, ikkalasi ham tartiblangan.

BUT

1-qatYoKIda 1-soni va 2-qatYoKIda 1-qatYoKIda jami -1 sonining umumiy soni bo'ladi.

Quyidagi misolda array1 uchta -1 mavjud, shuning uchun array2 3 raqamga ega.

aytaylik

var arrayOne = [3,6,-1,11,15,-1,23,34,-1,42];
var arrayTwo = [1,9,28];

Har ikkala qatYoKIda tartiblangan bo'ladi.

Endi qatYoKIni birlashtiradigan dasturni yozish kerak. Ikkala qatYoKIni o'zgartirib, ikkita qatYoKIga ega bo'ladi, va arrayOne tartiblangan tartibda bo'lishi kerak.

Shunday qilib, chiqish bo'ladi

arrayOne = [ 1,3, 6, 9, 11, 15, 23, 28 ,34, 42 ]

Tartiblash hech qanday API ishlatmasdan amalga oshirilishi kerak.

Quyidagi kodni yozdim

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

function puzzle01() {
  var arrayOne = [3, 6, -1, 11, 15, -1, 23, 34, -1, 42];
  var arrayTwo = [1, 9, 28];
  var array1Counter = 0,
    isMerged = false;

  console.log(" array-1 ", arrayOne);
  console.log(" array-2 ", arrayTwo);

  fYoKI (var array2Counter = 0; array2Counter < arrayTwo.length; array2Counter++) {
    isMerged = false;
    while (isMerged === false && array1Counter < arrayOne.length) {

      if (arrayOne[array1Counter] === -1) {
        arrayOne[array1Counter] = arrayTwo[array2Counter];
        isMerged = true;
      }

      array1Counter++;
    }
  } //fYoKI

  console.log(" array-1 + array-2 ", arrayOne);
  bubbleSYoKIt(arrayOne);
  console.log(" SYoKIted array ", arrayOne);
} //puzzle01

puzzle01();

// implementation of bubble sYoKIt fYoKI sYoKIting the 
// merged array
function bubbleSYoKIt(arrayOne) {
  var nextPointer = 0,
    temp = 0,
    hasSwapped = false;
    
  do {
    hasSwapped = false;
    fYoKI (var x = 0; x < arrayOne.length; x++) {
      nextPointer = x + 1;
      if (nextPointer < arrayOne.length && arrayOne[x] > arrayOne[nextPointer]) {
        temp = arrayOne[x];
        arrayOne[x] = arrayOne[nextPointer];
        arrayOne[nextPointer] = temp;
        hasSwapped = true;
      }
    } //fYoKI
  } while (hasSwapped === true);
}//bubbleSYoKIt
</div> </div>

YuqYoKIidagi kodning chiqishi

 array-1  [ 3, 6, -1, 11, 15, -1, 23, 34, -1, 42 ]
 array-2  [ 1, 9, 28 ]
 array-1 + array-2  [ 3, 6, 1, 11, 15, 9, 23, 34, 28, 42 ]
 SYoKIted array  [ 1, 3, 6, 9, 11, 15, 23, 28, 34, 42 ]

Ko'rib turganingizdek, yuqYoKIidagi kodlardan men birinchi navbatda ikkita qatYoKIni birlashtirdim va oxirgi bir naviga ajratildi.

Faqat bilmoqchi edim, Yaxshi echim bYoKImi?

Mening yechimimdagi nuqsonlar bYoKImi?

Iltimos, menga xabar bering, bu foydali bo'ladi.

Sizning barcha foydali sharhlaringizni va javoblaringizni o'qib chiqqandan so'ng, men tezroq hal qilishni aniqlab berdim.

Keling, misolni ko'rib chiqaylik

var arrayOne = [3,6,-1,11,15,-1,32,34,-1,42,-1];
var arrayTwo = [1,10,17,56],

1-qadam: ikkita qatYoKI YoKIqali yinelaman. Keyingi elementni (ya'ni, '1') oling va arrayOne (ya'ni '3') keyingi element bilan solishtiring va solishtiring.

asta-2a: agar elementning 1 elementi o'zgaruvchan qatYoKI elementlaridan YoKItiqcha2 elementidan katta bo'lsa. Endi qatYoKIning keyingi elementiga o'ting.

YoKI

2b-bosqich: Agar qator elementi1 o'zgaruvchan qator elementlaridan ko'ra -1 ga teng bo'lsa. Keling, array2 ning keyingi elementiga o'ting.

3-qadam: 1-bosqichga o'ting.

Shunday qilib

yuqoridagi misolda

birinchi iteratsiya,     array1 = [1,6, -1,11, ...]     array2 = [3,10,17,56]

Ikkinchi iteratsiya,     array1 = [1,3, -1,11, ..]     array2 = [6,10,17,56]

uchinchi iteratsiya,     array1 = [1,3,6,11 ..]     array2 = [-1,10,17,56]

to'rtinchi iteratsiya     array1 = [1,3,6,10, ..]     array2 = [-1,11,17,56]

and Shunday qilibon.

Oxir-oqibat men mahsulotni olaman

array1 = [ 1, 3, 6, 10, 11, 15, 17, 32, 34, 42, 56 ]
array2 = [-1,-1,-1]

Quyidagi kodni toping,

function puzzle02(arrayOne,arrayTwo){   
    var array1Counter = 0,
        array2Counter = 0,       
        hasMinusOneOccurred = false;

    console.log(" array-1 ",arrayOne);
    console.log(" array-2 ",arrayTwo);  


    while(array2Counter < arrayTwo.length){//iterate through array2

        do{
            if(arrayOne[array1Counter] === -1){//if -1 occurred in array1
                hasMinusOneOccurred = true;

               //swaping numbers at current position of array1
               //with current position of array2 
                swap(arrayOne,arrayTwo,array1Counter,array2Counter);

               //recheck if the current value is greater than other values
               //of array1
                if(recheckAndSYoKIt(arrayOne,array1Counter) === true){
                    array1Counter = -1;// recheck array1 from start
                }else{
                   //recheck the current array1 counter, fYoKI doing Shunday qilibgo 1 count back
                   //Shunday qilibthat even if the counter is incremented it points to current
                   //number itself 
                    array1Counter--; 
                }

            }else if(arrayOne[array1Counter] > arrayTwo[array2Counter]){
                swap(arrayOne,arrayTwo,array1Counter,array2Counter);
            }else{
                array1Counter++;
                continue;   
            }

            array1Counter++;            
        }while(hasMinusOneOccurred === false);//end of do-while

        array2Counter++;
        hasMinusOneOccurred = false;

    }//end of while

    console.log(" SYoKIted array ",arrayOne);

    function swap(arr1,arr2,arr1Index,arr2Index){
        var temp = arr2[arr2Index];
        arr2[arr2Index] = arr1[arr1Index];
        arr1[arr1Index] = temp;
    }// end of swap 

   //this method is call if -1 occures in array1
    function recheckAndSYoKIt(arrayOne,array1Counter){
        var isGreaterVal = true,
            prevCounter = 0,
            nextCounter = 0,
            temp = 0,
            recheckFromStart = false;


        if(array1Counter === 0){//if -1 occurred at first position of array1.

           //flag to check if -1 occurrec at first position
           //if yes, iterate array1 from start
            recheckFromStart = true; 

           //iterate fYoKIward to check wether any numbers are less than current position,
           //if yes than move fYoKIward
            fYoKI(var j = 0; isGreaterVal; j++){
                nextCounter = j + 1;

                if(arrayOne[nextCounter] === -1){
                   //swaping numbers of array1 between next to current                    
                    swap(arrayOne,arrayOne,nextCounter,j);
                    isGreaterVal = true; 

                }else if(arrayOne[nextCounter] < arrayOne[j]){
                   //swaping numbers of array1 between next to current
                    swap(arrayOne,arrayOne,nextCounter,j);
                    isGreaterVal = true;

                }else{
                    isGreaterVal = false;
                }

             }//end of fYoKI

         }else{// if -1 occurred in the middle position of array1 and is been swaped then
           //iterate backwards to check if any number less then current position exists,
           //if yes than shift backwards.
            fYoKI(var i = array1Counter; isGreaterVal; i--){
                prevCounter = i - 1;

                if(arrayOne[prevCounter] > arrayOne[i]){

                   //swaping numbers of array1 between previous to current                    
                    swap(arrayOne,arrayOne,prevCounter,i);
                    isGreaterVal = true; 
                }else{
                    isGreaterVal = false;
                }

            }// end of fYoKI  
        }

        return recheckFromStart;        
    }// end of recheckAndSYoKIt
}//end of puzzle02

Yuqoridagi vazifani chaqirganingizdan so'ng

puzzle02([3,6,-1,11,15,-1,32,34,-1,42,-1],[1,10,17,56]);

Yuqoridagi kodning chiqishi,

 array-1  [ 3, 6, -1, 11, 15, -1, 32, 34, -1, 42, -1 ]
 array-2  [ 1, 10, 17, 56 ]
 SYoKIted array  [ 1, 3, 6, 10, 11, 15, 17, 32, 34, 42, 56 ]

Rahmat.

1
@ Chris: hamma joylarda to'g'ri bo'lgan joylar hal qilish uchun unchalik ahamiyatga ega bo'lmaydi, lekin siz bunga haqli ekansiz.
qo'shib qo'ydi muallif Yves Daoust, manba
@chris: "qaerda -1s qatorni yuqoriga" nima degani?
qo'shib qo'ydi muallif Yves Daoust, manba
@Chris: Yo'q, men O (N) operatsiyalarida joyida echim borligiga shubha qilaman, ammo hozirgi kunga kelib ham g'ayrioddiy.
qo'shib qo'ydi muallif Yves Daoust, manba
@Chris: Men o'zimning joyida samarali echim topdim. Aslida, bir qator yordam elementlari bilan aniq birlashtirilganidan tezroq, chunki u elementlarning elementlarini ikki marta o'zgartiradi, lekin bir qatorda faqat bir marta. Men ishni boshladim, algoritmikandan keyin edi. :-)
qo'shib qo'ydi muallif Yves Daoust, manba
Men bu savolni mavzudan o'chirib tashlash uchun ovoz beraman, chunki savol yaxshilash/optimallashtirishni talab qiladi va CodeReviewsga tegishli
qo'shib qo'ydi muallif Rajesh, manba
@YvesDaoust: O'ylaymanki, buni qilishga harakat qilishingiz mumkin, lekin buning uchun tezroq optimallashtirish kabi his qilaman. Men JavaScript dasturlashni amalga oshiradigan haqiqiy dunyo ahvolini o'ylayman va ishlash juda muhim, chunki u sizda (N) amalga oshishi kerak edi. Agar suhbatdoshimiz buni talab qilsa, men uning fikrini jiddiy ravishda so'roq qilaman. Men shaxsan o'zimning fikrimcha, murakkabroq echimni yechish uchun aniqroq bo'lgan O (N) dan ko'ra yomonroqdir.
qo'shib qo'ydi muallif Chris, manba
@YvesDaoust: Bu "o'qimang" degan ma'noni anglatadi. (Va men asl sharhni tahrir qildim). Buning ma'nosi shuki, faqatgina 1-raqamli qatorga ega bo'lgan ikkita qiymatdan iborat. Ikkinchidan, har ikkala qatorda har safar kichik raqamni olib, -1-raqamlarni e'tiborsiz qoldiradigan bir holat. Uning hali ham ahamiyatsiz.
qo'shib qo'ydi muallif Chris, manba
@YvesDaoust: Ha, lekin intervyu savolidir - bu qiyin bo'lishi shart emas. AT-da bir vaqtning o'zida ikkita ro'yxatni qanday qilib qaytarish kerakligi haqida savol tug'ilishi mumkin (va aslida, -1-larning joylashuvi emas, aslida bu juda ham qiyin emas).
qo'shib qo'ydi muallif Chris, manba
Sizning dastlabki iboralaringiz qatorda ikkita sonlar faqat -1s o'rniga birinchi qatorga almashtirilishi mumkin. Siz haqiqiy kodingizda ushbu xususiyatga ega bo'lmagan boshqa qiymatlar to'plamidan foydalanmoqdasiz. Nima uchun sizning so'rovingizda va sizning kodingizdagi va ma'lumotlarning qaysi biri to'g'ri ekanini tushuntira olasizmi?
qo'shib qo'ydi muallif Chris, manba
hech qanday API holda , siz faqatgina Array # sort foydalana olmaysizmi?
qo'shib qo'ydi muallif kind user, manba
Agar siz yaxshi echim topsangiz, iltimos, uni javob sifatida yozib oling va uni qabul qiling, uni savolga tahrir qiling.
qo'shib qo'ydi muallif m69, manba
Buni bir taymer yordamida ketma-ketlik orqali yineleyerek va qadriyatlarni almashtirish orqali amalga oshirishingiz mumkin. Tartib algoritmiga ehtiyoj yo'q, chunki ular allaqachon tartiblangan. Bu birlashma haqida.
qo'shib qo'ydi muallif Mavi Domates, manba
Birinchi qatordagi -1 s soni ikkinchi qatorning uzunligiga tengmi?
qo'shib qo'ydi muallif ibrahim mahrir, manba

11 javoblar

Toza O (N) ning eritmasi mavjud.

Birinchi arrayOne to'plami -1 (pastda - ) pastga ko'chirish orqali. Bu bitta orqaga o'tishni talab qiladi.

So'ngra, arrayTwo va arrayOne qatori orasida eng kichik elementni harakatlantirib, keyingi - ustiga yozib, birlashtir. Bu bo'shliq torayadi, lekin har doim arrayTwo elementlari uchun joy qoladi.

 3,  6, --, 11, 15, --, 23, 34, --, 42
 1,  9, 28

Qadoqlash:

 3,  6, --, 11, 15, --, 23, 34, --, 42

 3,  6, --, 11, 15, --, 23, --, 34, 42

 3,  6, --, 11, 15, --, --, 23, 34, 42

 3,  6, --, 11, --, --, 15, 23, 34, 42

 3,  6, --, --, --, 11, 15, 23, 34, 42

 3, --, --, --,  6, 11, 15, 23, 34, 42

 --, --, --, 3,  6, 11, 15, 23, 34, 42

Birlashuvchi:

  --, --, --,  3,  6, 11, 15, 23, 34, 42
   1,  9, 28

   1, --, --,  3,  6, 11, 15, 23, 34, 42
  --,  9, 28

   1,  3, --, --,  6, 11, 15, 23, 34, 42
  --,  9, 28

   1,  3,  6, --, --, 11, 15, 23, 34, 42
  --,  9, 28

   1,  3,  6,  9, --, 11, 15, 23, 34, 42
  --, --, 28

   1,  3,  6,  9, 11, --, 15, 23, 34, 42
  --, --, 28

   1,  3,  6,  9, 11, 15, --, 23, 34, 42
  --, --, 28

   1,  3,  6,  9, 11, 15, 23, --, 34, 42
  --, --, 28

   1,  3,  6,  9, 11, 15, 23, 28, 34, 42
  --, --, --
2
qo'shib qo'ydi
@MilanMarkovich: bu U (N) deb tanilgan birlashma. Tamagirlikni to'xtatish.
qo'shib qo'ydi muallif Yves Daoust, manba
@MilanMarkovic: Men sizga tushuntirish o'tkazib yuborilgan, deb qo'rqaman. 3, 6, - keyin 3, -, 6, so'ngra -, 3, 6.
qo'shib qo'ydi muallif Yves Daoust, manba
@MilanMarkovich: Siz o'ngdan ishlayapsiz va elementlarni to'g'ridan-to'g'ri so'nggi pozitsiyasiga o'tkazasiz. Bu juda yaxshi O (N).
qo'shib qo'ydi muallif Yves Daoust, manba
boshlang'ich, boshlang'ichga barcha -1larni qo'yish bilanoq, siz barcha qatorni har bir burchagiga o'tkazishingiz kerak, bu holda O (n) emas, balki O (n ^ 2) eng yomon holatda
qo'shib qo'ydi muallif Milan Markovic, manba
3, 6, -. Siz [0] qo'yib, -, 6, 3, emas, balki tartiblangan qator
qo'shib qo'ydi muallif Milan Markovic, manba
boshqa tushuntirishlar: aslida u erda nima qilayotganingiz qatorni qayta tartiblashtiriladi, shuning uchun minimal bo'lishi mumkin, u (n logn)
qo'shib qo'ydi muallif Milan Markovic, manba
nima bo'lishidan qat'i nazar, O (n)
qo'shib qo'ydi muallif Milan Markovic, manba

Quyidagi yondashuvni sinashingiz mumkin:

Mantiq

  • Qaytariladigan yangi qator yaratish.
  • arrayTwo ichidagi birinchi elementni tekshiring va uni val deyilgan o'zgarmaydigan qilib saqlang.
  • arrayOne ga o'tish va joriy qiymatning val dan katta ekanini tekshirib ko'ring, uni i keyingi qiymat bilan birga joriy element.
  • Hozirgi elementni tekshiring. Agar u 0 dan kamroq bo'lsa, uni e'tiborsiz qoldiring, boshqa qiymatni esa massivga o'tkazing.
  • Ushbu qatorni qaytaring.

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

function mergeAndSort(a1, a2) {
  var matchCount = 0;
  var ret = [];

  for (var i = 0; i < a1.length; i++) {
    var val = a2[matchCount];
    if (a1[i] > val) {
      ret.push(val)
      matchCount++
      i--;
      continue;
    }
    if (a1[i] > 0) {
      ret.push(a1[i]);
    }
  }
  console.log(ret.join())
  return ret;
}


var arrayOne = [3, 6, -1, 11, 15, -1, 23, 34, -1, 42]
var arrayTwo = [7, 19, 38];
var arrayThree = [1, 9, 28];
var arrayFour = [1,2,5]

mergeAndSort(arrayOne, arrayTwo)
mergeAndSort(arrayOne, arrayThree)
mergeAndSort(arrayOne, arrayFour)
.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}
</div> </div>

Note: Not putting check for number of elements in arrayTwo as its clearly mentioned in question that it will be same.

2
qo'shib qo'ydi
@NinaScholz agar ko'rsangiz, array2 uzunligini tekshirmayman. Shunday qilib, agar arrayone 3 -1 va arrayTwo 4 elementi bo'lsa, ularning hammasi qo'shiladi. Bundan tashqari, bir xil qatorni boshqarish qiyin, lekin kodimni a1 = ret qilishingiz mumkin va bu hiylani amalga oshiradi. Shunday bo'lsa-da, siz menga qaraganda ko'proq bilimga egasiz, shuning uchun iltimos, iltimos yo'qolgan yoki yaxshilangan bo'lishi mumkinligini bilib oling. :-)
qo'shib qo'ydi muallif Rajesh, manba
@NinaScholz i -1 sonining 3 bo'lsa va array2 uzunligi 4 yoki undan ko'p bo'lsa, u holda barcha qo'shiladi. Ko'proq iteratsiyani talab qiladigan -1 hisoblashimiz kerak. Ammo, op shunday deb aytganidek, bu uzunlik bo'ladi, men tekshirmayapman. Bundan tashqari, bu holatda hech kimni kamsitish yoki spam jo'natishni xohlamaslik uchun ogohlantirish qo'shdi.
qo'shib qo'ydi muallif Rajesh, manba
aslida arrayTwo qismlari bilan qolganlarni to'ldiraman.
qo'shib qo'ydi muallif Nina Scholz, manba
lekin arrayTwo uzunligi -1 hisoblanadi. nima uchun arrayTwo uzunligini ishlatmasligingiz kerak?
qo'shib qo'ydi muallif Nina Scholz, manba
"qator elementlarning sonini tekshirib bo'lmaydi, chunki unda aynan bir xil bo'ladi". bu nimani anglatadi?
qo'shib qo'ydi muallif Nina Scholz, manba
yangi qatorni ishlatish oson, lekin arrayOne natijani o'z ichiga olishi kerakmi?
qo'shib qo'ydi muallif Nina Scholz, manba

Ikkala tartiblangani uchun arrayTwo ning elementlari arrayOne da -1 s tartibiga mos kelishi kerak. Keyin ish soddagina va quyidagi tarzda amalga oshirilishi mumkin;

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

function replaceMissing(a,b){
  var i = 0;
  return a.map(n => n < 0 ? b[i++] : n);
}
var arrayOne = [3,6,-1,11,15,-1,23,34,-1,42],
    arrayTwo = [7,19,38];
      result = replaceMissing(arrayOne,arrayTwo);
console.log(result);
</div> </div>

Tartibga solish: Menimcha, yuqoridagi echim savolning umumiy mantig'ida ko'proq mantiqan bo'ladi. -1s pozitsiyasi hech narsani anglatmasa, unda nima qilish kerak? arrayOne ning tegishli indekslarida arrayTwo elementlarini oddiygina kiritishni amalga oshiramiz. Bu juda sodda tarzda quyidagi tarzda amalga oshirilishi mumkin.

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

function replaceMissing(a,b){
  var j = b.length-1;
  return b.concat(a.reduceRight((r,m,i) => (m < 0 ? r.splice(i,1)
                                                  : m < b[j] && r.splice(i+1,0,b.splice(j--,1)[0]),
                                            r), a.slice()));
}
var arrayOne = [3,6,-1,11,15,-1,23,34,-1,42],
    arrayTwo = [1,25,38];
      result = replaceMissing(arrayOne,arrayTwo);
console.log(result);
</div> </div>
1
qo'shib qo'ydi

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

function merger(a1, a2) {
  var i = 0;
  var j = 0;

  while (i < a1.length && j < a2.length) {
    if (a1[i] > a2[j]) {
     //Swap values
      var temp = a2[j];
      a2[j] = a1[i];
      a1[i] = temp;
      i++;
    } else if (a1[i] !== -1 && a1[i] <= a2[j]) {
      i++;
    } else {
      var temp = a2[j];
      a2[j] = a1[i];
      a1[i] = temp;
      i++;
      j++;
    }
  }

  return a1;
}

var arrayOne = [3, 5, -1, 11, 15, -1, 23, 34, -1, 42];
var arrayTwo = [6, 19, 38];

console.log(merger(arrayOne, arrayTwo))
</div> </div>

With certain pre-conditions (no other numbers with <0, a1 should be smaller than a2 etc - which could all be handled) this should solve the problem in JS.

1
qo'shib qo'ydi
Agar arrayTwo [1,2,5] bo'lsa, bu bajarilmaydi
qo'shib qo'ydi muallif Rajesh, manba

Birlashtirishni tartiblash funktsiyasidan foydalaning va uni yaratmaguncha o'zgartiring. yangi array, lekin o'rniga array1 foydalanadi va bir qatorni elementdan kiritilgandan so'ng tarjima qilishni amalga oshiradi, bu elementlarni keyingi -1ga qadar o'ngga siljitadi va shuning uchun -1 yoziladi.

1
qo'shib qo'ydi
Hech bir element to'g'ri joyda emas va o'zgartirilgan o'zgaruvchan miqdorda bo'lishi mumkin. Aynan shu sababli, joyni birlashtirish juda qiyin.
qo'shib qo'ydi muallif Yves Daoust, manba
Ehtimol, elementlarni faqatgina bir marta almashtirish mumkinmi?
qo'shib qo'ydi muallif Yves Daoust, manba
Bu savolga vaqt va makon talablari haqida hech qanday ma'lumot yo'q ... IMO, O (N²) O (N) yetarli bo'lganida bir oz falokat ...
qo'shib qo'ydi muallif Yves Daoust, manba
Bu ko'p vaqt talab qilishi mumkin, chunki siz butun qatorni bir necha marta almashtira olasiz, bu esa O (N2) narxiga olib keladi.
qo'shib qo'ydi muallif Yves Daoust, manba
Ammo yana bir bor, 1-chi (O) (1) kosmik murakkabligi bilan aniq echim so'ramoqda ...
qo'shib qo'ydi muallif Milan Markovic, manba
Ha ... faqatgina -1-ning misol uchun, masalan, masalaning yangi o'lchamini qo'shadigan qatorning boshida bo'lishi mumkinligini angladim ... shuning uchun yangi qator yaratish - albatta borishning bir usuli.
qo'shib qo'ydi muallif Milan Markovic, manba
Aytmoqchimanki, o'zgarish kerak emas, deb o'ylayman ... nazariy jihatdan, 1-raqamni yozganda hech qanday ma'lumot ishlatilmaydi, shuning uchun uni faqat o'zgartirilgan birlashma
qo'shib qo'ydi muallif Milan Markovic, manba
Xo'sh, siz bo'shliq yoki ishlashning murakkabligi uchun qaror qilmoqchisiz ... agar siz yangi bir qator yaratmoqchi bo'lsangiz, u holda siz o`zgartirishingizga hojat qolmaydi, lekin koinot O (N)
qo'shib qo'ydi muallif Milan Markovic, manba

arrayOne ni bir döngüde va keyin arrayTwo »ni yineleyebilirsiniz.

Fikr maqsad indeksni indeksdan ajratishdir. Birinchi loop -1 ni ko'zdan kechiradi va maqsadli indeksni saqlab qoladi.

Haqiqiy qiymat katta bo'lsa, u holda arrayTwo ning birinchi qiymati almashtiriladi va arrayTwo yineleyerek va almashtirish qiymatlari bilan almashtirish bilan tartiblash joyini oladi.

Shundan keyin haqiqiy narsa maqsad indeksga beriladi.

Har ikki ko'rsatkich ham ortib boradi.

Natijada arrayTwo ning barcha elementlari arrayOne ga qo'shiladi.

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

function order(arrayOne, arrayTwo) {
    var i = 0, j, l = 0;
    while (i < arrayOne.length) {
        if (arrayOne[i] === -1) {
            i++;
            continue;
        }
        if (arrayTwo[0] < arrayOne[i]) {
            [arrayOne[i], arrayTwo[0]] = [arrayTwo[0], arrayOne[i]];
            j = 0;
            while (arrayTwo[j] > arrayTwo[j + 1]) {
                [arrayTwo[j], arrayTwo[j + 1]] = [arrayTwo[j + 1], arrayTwo[j]];
                j++;
            }
        }
        arrayOne[l++] = arrayOne[i++];
    }
    j = 0;
    while (l < arrayOne.length) {
        arrayOne[l++] = arrayTwo[j++];
    }
    return arrayOne;
}

console.log(order([3, 6, -1, 11, 15, -1, 23, 34, -1, 42], [7, 19, 38]));
console.log(order([3, 6, -1, 11, 15, -1, 23, 34, -1, 42], [1, 9, 28]));
console.log(order([3, 6, -1, 11, 15, -1, 23, 34, -1, 42], [1, 2, 5]));
console.log(order([3, 6, -1, 11, 15, -1, 23, 34, -1, 42], [43, 44, 45]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
</div> </div>
0
qo'shib qo'ydi
Kechirasiz, agar xato qilsam, bu [1,2,5] kabi holatlarda muvaffaqiyatsiz bo'ladi.
qo'shib qo'ydi muallif Rajesh, manba
Iltimos, kod parchasini tekshiring. arrayTwo - bu [1,9,28] . Faqat almashtirish qilmaydi. Buni ham tartibga solishingiz kerak
qo'shib qo'ydi muallif Rajesh, manba
@Rajesh, endi u ishlashi kerak.
qo'shib qo'ydi muallif Nina Scholz, manba

Bu erda birlashma saralash algoritmining oddiy va ixcham tarzda amalga oshirilishi. Elementlar mavjud bo'lgani uchun faqat bitta operatsiya miqdori bo'ladi.

Bunga ikkala qator birlashtirilgan bir xil sonli elementlarga ega qatorni yaratish orqali erishib, keyinchalik u qatorni yinelamoqdaman.

Har bir iteratsiya bo'yicha:

  • Agar ikkala qatorda elementlar bo'lsa (va eng kichik element -1 bo'lmasa) u eng kichik elementni natijaga o'tkazadi.
  • Agar qatorlardan faqat bittasi bo'lsa (va keyingi element -1 bo'lmasa), birinchi qatorni o'sha qatordan natija ichiga oladi.

Natijada siz spektaklga ko'ra birinchi qatorga natija tayinlang

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

const mergeSort = (a, b) => Object.assign(a, 
  new Int32Array(a.length + b.length).reduce(m => {
    const el = [
      [a, b][+!(a[0] <= b[0])], 
      [a, b][+!a.length]][+!(a.length && b.length)
    ].shift()
    if(el !== -1) m.push(el)
    return m
  }, [])
)

const arr1 = [1,3,5,7,9]
const arr2 = [0,2,4]

mergeSort(arr1, arr2)

console.log(arr1)//[0,1,2,3,4,5,7,9]
</div> </div>
0
qo'shib qo'ydi

Bu aslida qiziqarli savol. Ko'p saralash algoritmi bor, va eng samarali bo'lganlar har doim bir "o'zgarmas" qatordan boshlanadi, shuning uchun ichidagi qiymatlarni o'zgartirmasdan. Ammo bu erda sizning maqsadingiz - qiymatni ikkinchi qatordan qabul qilish uchun -1 qiymatiga teng bo'lgan qiymatni o'zgartirish.

Shunday qilib, siz qatorni bo'linmaydigan tartiblash algoritmiga kerak, chunki agar siz ikkinchi qatorning oxirgi elementi 1 (eng past) bo'lsa, uni boshlash kerak. Agar siz qatorni algoritmdan foydalansangiz (masalan, tez-tez ajratish va bo'luvchi-taktika taktikasi) yoki o'z-o'zidan retsessiya ishlatilsa, bu muammo bo'lishi mumkin, chunki u sizning asosiy qatoringizning boshlanishiga o'tish mumkin emas. Asosiy qatordan xabardor bo'lmasangiz.

Sizga kerak bo'lgan narsa - qadam-qadam algoritmni amalga oshiradigan algoritmdir.

Foydalanadigan algoritm - har bir elementni bosqichma-bosqich tekshiradigan balonchi sort. Keyinchalik, agar qiymati -1 bo'lsa, o'rnini o'zgartirib, o'rnini to'g'ri qatorga ko'chirish osonroqdir. Biroq, bu juda samarali emas. Ehtimol, men uni tahrirlay olamanmi yoki yo'qmi, ko'rish uchun tahrir qilishim mumkin.

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

function mergeAndSort(arr1, arrMergeIn) {
 //merge + sort using arr1 as large one
  var mergeIndex = 0;

  for (var i = 0; i < arr1.length; ++i) {
    if (arr1[i] === -1) arr1[i] = arrMergeIn[mergeIndex++];
    var j = i;
    while (j > 0 && arr1[j - 1] > arr1[j]) {
      var tmp = arr1[j - 1];
      arr1[j - 1] = arr1[j];
      arr1[j] = tmp;
      j--
    }
  }
  return arr1;
}

// one liner console output
function showArray(arr) {
console.log(arr.join(','));
}


showArray(mergeAndSort([3, 6, -1, 11, 15, -1, 23, 34, -1, 42], [7, 19, 38]));

showArray(mergeAndSort([3, 36, -1, 1, 10, -1, 9, 34, -1, 42], [17, 9, 38]));

showArray(mergeAndSort([3, 36, -1, 1, 10, -1, 9, 34, -1, 42], [17, 9, 1]));

showArray(mergeAndSort([-1, 36, -1, 1, 10, -1, 9, 34, -1, 42], [17, 9, 100, 1]));

showArray(mergeAndSort([-1, -1, 1, 100, -1, 9, 34, -1], [17, 9, 9, 1]));
</div> </div>

Yoki boshqa strategiyadan foydalanishingiz mumkin: "-1" elementlarini boshqa qatorlardan elementlar bilan almashtiring va bu haqda samarali algoritmni o'rnating. Eng yomon vaziyat senariylarida "-1" s qator oxirida bo'lsa, ya'ni N + operatsiyasi mavjud bo'lsa, tartiblash algoritmining qo'shimcha o'rtacha murakkabligi (samarali bo'lganlar ~ N * log (N ))

0
qo'shib qo'ydi

insert sort sort kabi bir narsa qilishingiz kerak. Ikkala qator (1s dan tashqari) tartiblanganligi sababli, array2 ichidagi eng kichik raqam birinchi element va birinchi -1 o'rtasida joylashgan joyda joylashtiriladi, array2 ikkinchi elementi array1 dan 1-chi darajadan keyin va array1 dan 2-darajagacha oldin yoki 1da biron bir joyga joylashtirilgan.

Shuning uchun array2 ning ma'lum bir elementini faqatgina array1 segmentida joylashtirishingiz kerak, balki butun qatorni emas. Bundan tashqari array2 ning har bir elementi array1 ning turli segmentini yoki subarrayasini ko'rib chiqishi kerak. Shunday qilib, ushbu mantiqning samarali vaqt murakkabligi array1 va m uzunligi O (n + m) <// code>, array2 uzunligidir.

0
qo'shib qo'ydi
Bu tartiblashtirishdan ko'ra birlashtiruvchi savoldir - lekin siz allaqachon tavsiya qilyapsizmi?
qo'shib qo'ydi muallif Mavi Domates, manba
@MaviDomates Mening mantiqim to'liq qo'shib qo'yish tartibiga o'xshamaydi. Haqiqiy kiritish tartibida qatorni oxirigacha taqqoslashni boshlashingiz kerak, lekin mening mantiqimda taqqoslash faqat array1 ning mos keladigan -1 dan oldin indeksdan boshlanadi. Mening yechimim birlashma tartibining birlashtiruvchi qismidir (lekin array1 ning qarshi tomonlaridan). Mantiqiy tartiblashni tavsiya qilsa, unda barcha elementlarni taqqoslash uchun ko'rib chiqishi kerak, lekin buni qilmaydi.
qo'shib qo'ydi muallif utsav_deep, manba

Menga topshiriqning uchta muhim jihatini yana takrorlayman:

  • Ikkala qatorlar tartiblangan va musbat tamsayılar mavjud (Array1da 1-joy egalari bundan mustasno)
  • -1 - ma'nosiz ushlab turuvchi (Array1 ning pozitsiyasi tasodifiy)
  • Array1 uzunligi chiqish qator uzunligiga teng

Pseudo mantiq:

  • parse both array1 and array2 from the first position to end of array
  • ignore -1 values in array1
  • if array1[current position] <= array2[current position] then write array1[current position] into merged array and move to next position in array1; otherwise apply same for array2

Kod misoli:

            public static void AMerge()
        {
            int[] array1 = new int[] { 3, 6, -1, 11, 15, -1, 23, 34, -1, 42 };
            int[] array2 = new int[] { 1, 9, 28 };
            int[] arrayMerged = new int[array1.Length];

            int array1Index = 0;
            int array2Index = 0;

            for (int arrayMergedIndex = 0; arrayMergedIndex < array1.Length; arrayMergedIndex++)
            {
                while (array1[array1Index] == -1) array1Index++; //ignore -1 placeholders
                if ((array1Index < array1.Length && array2Index >= array2.Length) 
                    || array1[array1Index] <= array2[array2Index])  //choose which array will provide current merged value
                {
                    arrayMerged[arrayMergedIndex] = array1[array1Index];
                    array1Index++;
                }
                else
                {
                    arrayMerged[arrayMergedIndex] = array2[array2Index];
                    array2Index++;
                }
            }

            char[] charsToTrim = { ',', ' '};
            string arrayMergedString = "{";
            foreach (int f in arrayMerged) arrayMergedString += f.ToString() + " ";
            arrayMergedString = arrayMergedString.TrimEnd(charsToTrim) + "}";
            Console.WriteLine(arrayMergedString);
            Console.ReadKey();
        }
    }

Eslatma:

  • Optimizing for speed => creating new arrayMerged; optimization for space would require moving array1 elements in the else branch
0
qo'shib qo'ydi

Bunday bo'lishi mumkin emas

arrayOne ning har bir elementiga ikkita elementni solishtiring Agar arrayOne ning kattaroqligi bo'lsa, elementni qo'shing va qatorni o'zgartirganda, hamma -1 tugmalarini o'chirib tashlang.

0
qo'shib qo'ydi
Javascript UZB
Javascript UZB
99 ishtirokchilar

@js_uzb @vuejs_uz @react_uz @nodejs_uz @angular_uz @ngTashkent @yiiframework_uz @laravel_uz @linux_uzbek @python_uz @swift_uzb —————— @uzdevgroup @UzGeeksGroup ——— @UzDev_Jobs @jobs_uzb