سلام . عیدتون مبارک باشه.


بخاطر مهم بودن بحثای هفته پیش این هفته سوالا مروری از دو هفته گذشته و یه روش خیلی پرکاربرد هستش به اسم TwoPointer.


Two Pointer : بیشتر به چشم یه بهبود دهنده ی سرعت الگوریتم ها میتونین بهش نگا کنین چون...بسته به مسئله میشه این روش رو جایگزین جستجوهای ساده ولی پرهزینه تر کرد.


بذارین با یه مثال بررسیش کنیم :

فرض کنین یه آرایه ی صعودی زیر رو داریم و دنبال 2 تا عدد از این مجموعه هستیم که مجموعشون برابر 22 باشه .

A = { 1 , 3 , 7 , 11 , 15 , 28 }

 یه روش ساده و پر هزینه اینه که با یه حلقه تودرتو تمام حالتای انتخاب 2 تا عدد رو چک کنیم و ببینیم برابر 22 میشه یا نه . ولی این میشه O(n^2) و تو آرایه های بزرگ جوابگو نیست . حالا بزارین این روش رو نگاه کنیم :

 i = 0 , j = 5;

while (i<j)

{

    k = a[i]+a[j];

    if (k == 22) { cout<<"OK"; break; }

    else if (k > 22) j--;

    else i++;

}

در واقع اول میایم دو تا اشاره گر اول و آخر آرایه میذاریم .

 - اگه جمعشون برابر 22 بود که جواب پیدا شده.

 - اگه بیشتر از 22 باشه باید جمع دو تا عدد رو کوچیکتر کنیم پس باید j رو بیاریم عقب تا روی عددای کوچیکتر بیفته .

 - اگرم که کمتر باشه باید i رو  ببریم جلو تا جمعشون رو بیشتر کنیم .

این الگوریتم O(n) هستش و خیلی بهتر از روش اول هستش .


مثال دوم : ترکیب دو تا آرایه مرتب:

فرض کنید 2 تا آرایه ی مرتب دارین و میخواین ترکیبشون کنین .

A  = { 1 , 3 , 5 , 8 }

B =  { 3 , 4 , 7 , 12 }

A + B -> C = { 1 , 3 , 3 , 4 , 5 , 7 , 8 , 12 }

میشه دو تا آرایه رو به هم وصل کرد و بعد سورتش کرد یا یکی رو تو اون یکی insert کرد. ولی با روش دو اشاره گر این کار خیلی سریعتره.


i = 0 , j=0

while (i<|A| && j<|B|)

{

    if (A[i] <= B[j]) -> add A[i] to C , i++

    else -> add B[j] to C , j++

}

while (i<|A|) -> add A[i] to C , i++

while (j<|B|) -> add B[j] to C , j++




مثالای دیگه :

- مسئله  Book هفته پیش که براش همینجا پست گذاشتیم .


یکم پیشرفته تر :

- جمع دو تا ماتریس spars

- پارتیشن بندی QuickSort

- پیدا کردن حلقه تو لینک لیست ، ...  ،  یوتیوب

و ... ... ....


مسابقه امشب شروع میشه. موفق باشین