มีอัลกอริทึมที่ค้นหาการเรียงลำดับขนาดที่สามในเวลาหรือไม่?


21

ฉันต้องการที่จะพิสูจน์หรือหักล้างการดำรงอยู่ของอัลกอริทึมที่ได้รับอาร์เรย์ของจำนวนเต็มพบสามดัชนีและดังกล่าวว่าและ (หรือพบว่าไม่มีสามเท่า) ในเวลาเชิงเส้นi , j k i < j < k A [ i ] < A [ j ] < A [ k ]Ai,jki<j<kA[i]<A[j]<A[k]

นี่ไม่ใช่คำถามทำการบ้าน ฉันเห็นมันในกรอบการเขียนโปรแกรมที่มีชื่อว่า“ พยายามใช้อัลกอริธึมเช่นนี้” ฉันสงสัยว่ามันเป็นไปไม่ได้หลังจากการทดลองต่างๆ สัญชาตญาณของฉันบอกฉันอย่างนั้น แต่มันก็ไม่นับรวมถึงสิ่งใด

ฉันต้องการพิสูจน์ว่าเป็นทางการ คุณจะทำอย่างไรมันได้หรือไม่? ฉันอยากเห็นหลักฐานที่วางไว้ทีละขั้นตอนและถ้าคุณมีความโน้มเอียงมากคำอธิบายว่าจะทำอย่างไรในการพิสูจน์ / หักล้างคำถามง่ายๆเช่นนี้โดยทั่วไป ถ้ามันช่วยได้ตัวอย่าง:

[1,5,2,0,3] → (1,2,3)
[5,6,1,2,3] → (1,2,3)
[1,5,2,3] → (1,2,3)
[5,6,1,2,7] → (1,2,7)
[5,6,1,2,7,8] → (1,2,7)
[1,2,999,3] → (1,2,999)
[999,1,2,3] → (1,2,3)
[11,12,8,9,5,6,3,4,1,2,3] → (1,2,3)
[1,5,2,0,-5,-2,-1] → (-5,-2,-1)

ฉันคิดว่ามันสามารถทำซ้ำได้มากกว่าและทุกครั้งที่มี (ปัจจุบันของเรานั่นคือ) เราสร้างทริปเปิลใหม่และผลักมันไปยังอาร์เรย์ เราก้าวต่อไปและเปรียบเทียบแต่ละสามจนกว่าหนึ่งในสามของเราเสร็จสมบูรณ์ มันก็เหมือนกัน! แต่ฉันคิดว่ามันซับซ้อนกว่าเพียงเนื่องจากจำนวนของ triples ใน array สามของเราในกรณีที่แย่ที่สุดนั้นตรงกับขนาดของรายการอินพุตi < j j O ( n )Ai<jj[1,5,2,0,-5,-2,-1] → 1..2.. -5.. -2.. -1[1,5,2,0,-5,-2,3,-1] → 1..2.. -5.. -2.. 3O(n)



โปรดทราบว่าในกรณีที่เลวร้ายที่สุด (อาร์เรย์ที่เรียงลำดับ) คุณยังมี triples ที่เหมาะสมจำนวนมาก โปรดพิจารณาให้อัลกอริทึมที่คุณเสนอเป็นรหัสหลอก ฉันคิดว่าคำอธิบายของคุณไม่สมบูรณ์ Θ(n3)
ราฟาเอล

คำตอบ:


14

นี่คือรูปแบบของปัญหาที่เพิ่มขึ้นที่ยาวที่สุด ; นี่เป็นวิธีแก้ปัญหาที่นำเสนอบน Wikipedia โดยใช้อาร์เรย์เสริมสองชุดและ :PMP

  • k [ k ] เจ[ k ] k ฉันเจk ฉันเจk 13 11 k ฉันM[j] - เก็บตำแหน่งของค่าที่เล็กที่สุดซึ่งมีการเรียงลำดับของความยาวลงท้ายด้วยขึ้นในช่วง (หมายเหตุเรามีนี่เพราะหมายถึงความยาวของ subsequence เพิ่มขึ้นและแสดงถึงตำแหน่งของการสิ้นสุดของมัน. แน่นอนเราไม่สามารถมี subsequence ที่เพิ่มขึ้นของความยาวตอนจบที่ตำแหน่ง .โดยความหมาย)kA[k]jA[k]kijkijk1311ki
  • A [ k ] A [ k ]P[k] - ร้านค้าตำแหน่งของบรรพบุรุษของในการเพิ่ม subsequence ที่ยาวที่สุดสิ้นสุดที่[k]A[k]A[k]

    นอกจากนี้อัลกอริทึมจะเก็บตัวแปรแสดงถึงความยาวของลำดับที่เพิ่มขึ้นที่ยาวที่สุดที่พบL

ขั้นตอนวิธีการนี้จะทำงานในเวลาที่เลวร้ายที่สุดกรณีn) ปัญหาของคุณได้เป็นกรณีพิเศษที่ช่วยให้คุณกลับมาเมื่อซึ่งผลักดันรันไทม์ลงไปเพราะค้นหา binary ทำงานเฉพาะในอาร์เรย์ของความยาวสองที่มากที่สุดซึ่งเป็นดังนั้นในเวลาเมื่อเทียบกับในกรณีทั่วไปL = 3 O ( n ) O ( 1 ) Θ ( log n )Θ(nlogn)L=3O(n)O(1)Θ(logn)

พิจารณาโค้ดหลอกที่แก้ไขแล้ว:

 L = 0
 for i = 1, 2, ... n:
    binary search for the largest positive j ≤ L
      such that X[M[j]] < X[i] (or set j = 0 if no such value exists)
    P[i] = M[j]
    if j == L or X[i] < X[M[j+1]]:
       M[j+1] = i
       L = max(L, j+1)
   if L==3 : return true; // you can break here, and return true.
return false; // because L is smaller than 3.

@ SaeedAmiri ฉันเห็นความคิดเห็น แต่ฉันไม่มีเวลาทบทวนเลย (ฉันโพสต์คำถามก่อนเข้านอน) ฉันสงสัยว่าจากลิงก์ของคุณว่ากรณีพิเศษของเรา L = 3 จะช่วยอย่างใด แต่ก็ไม่มีโอกาสเข้าใจรายละเอียด ขณะนี้ฉันอยู่ที่ทำงานและเวลา จำกัด มั่นใจได้ว่าฉันขอขอบคุณคำตอบของคุณ มันเป็นเพียงผิวเผินของฉันที่จะขอบคุณสำหรับมันโดยไม่เข้าใจทุกบรรทัดภายในมัน
Christopher เสร็จ

@ SaeedAmiri: ฉันเห็นด้วยที่คุณคาดหวังมากขึ้น "เติมช่องว่าง" ที่นี่ แต่คุณยังต้องให้ข้อโต้แย้งที่มุมของหลักฐาน (อย่างย่อ) แต่อย่างน้อย เกี่ยวกับ OP เขาดูเหมือนว่าจะอยู่ในอิตาลีดังนั้นอาจเป็นไปได้อย่างรวดเร็วระหว่างความคิดเห็นและคำตอบของคุณ (และโอกาสที่เขากำลังยุ่งอยู่กับตะวันออกในขณะนี้)
ราฟาเอล

@ChristopherDone ฉันไม่ต้องการทำให้คุณเสียใจเสียใจด้วยความผิดพลาดของฉันคุณพูดถูก

1: generalizes นี้เป็นอย่างดีทำให้เพียงหนึ่งผ่านและเป็นพื้นที่ O(1)
Aryabhata

ตกลงมันดูดี ฉันใช้เวลาสักครู่เพื่อค้นหาพฤติกรรมของอัลกอริทึมลำดับที่เพิ่มขึ้นทั่วไปที่ยาวที่สุด หลังจากนั้นความยาวสูงสุด == 3 การเปลี่ยนแปลงเป็นเรื่องปกติ ขอบคุณ!
Christopher เสร็จ

11

หมายเหตุเกี่ยวกับวิธีการ

ฉันคิดเล็กน้อยเกี่ยวกับปัญหานี้และหาทางแก้ไข เมื่อฉันอ่านคำตอบของ Saeed Amiriฉันรู้ว่าสิ่งที่ฉันคิดขึ้นมาคือรุ่นพิเศษของขั้นตอนการหาลำดับเบสมาตรฐานที่ยาวที่สุดสำหรับลำดับความยาว 3 ฉันโพสต์วิธีที่ฉันคิดวิธีแก้ปัญหาเพราะฉันคิดว่า เป็นตัวอย่างที่น่าสนใจในการแก้ปัญหา

รุ่นสององค์ประกอบ

ขอเริ่มต้นเล็ก ๆ แทนการมองหาสามดัชนีที่องค์ประกอบอยู่ในลำดับที่ดูให้ของสอง:ดังกล่าวว่า[เจ]A [ i ] < A [ j ]i<jA[i]<A[j]

ถ้ากำลังลดลง (เช่นหรือเทียบเท่า ) ดังนั้นไม่มีดัชนีดังกล่าว มิฉะนั้นมีดัชนีเช่นว่า1]Ai<j,A[i]A[j]i,A[i]A[i+1]iA[i]<A[i+1]

กรณีนี้ง่ายมาก เราจะพยายามพูดคุยกัน มันแสดงให้เห็นว่าปัญหาตามที่ระบุไม่สามารถแก้ไขได้: ดัชนีที่ร้องขอไม่ได้มีอยู่เสมอ ดังนั้นเราค่อนข้างจะถามว่าอัลกอริทึมจะส่งกลับดัชนีที่ถูกต้องหากมีอยู่หรืออ้างอย่างถูกต้องว่าไม่มีดัชนีดังกล่าว

เกิดขึ้นกับอัลกอริทึม

ฉันจะใช้ระยะsubsequenceหมายถึงสารสกัดจาก array ประกอบด้วยดัชนีที่ไม่อาจจะติดต่อกัน (กับ ) และเรียกใช้ค่าเฉลี่ย องค์ประกอบต่อเนื่องของ ( )A(A[i1],,A[im])i1<<imA(A[i],A[i+1],,A[i+m1])

เราเพิ่งเห็นว่าดัชนีที่ร้องขอนั้นไม่มีอยู่จริง กลยุทธ์ของเราคือการศึกษาเมื่อไม่มีดัชนี เราจะทำเช่นนี้โดยสมมติว่าเราพยายามค้นหาดัชนีและดูว่าการค้นหาของเราอาจผิดพลาดอย่างไร จากนั้นกรณีที่การค้นหาไม่ผิดพลาดจะมีอัลกอริทึมในการค้นหาดัชนี

4,3,2,1,0

ด้วยสองดัชนีเราสามารถหาดัชนีติดต่อกัน กับสามดัชนีที่เราอาจจะไม่สามารถที่จะเกิดขึ้นกับและ 1 อย่างไรก็ตามเราสามารถพิจารณากรณีที่มีองค์ประกอบสามอย่างที่เพิ่มขึ้นอย่างเข้มงวด ( ) ได้รับการแก้ไขเนื่องจากง่ายต่อการรับรู้การวิ่งดังกล่าว และดูว่าสภาพนี้อาจไม่เป็นไปตามเงื่อนไข สมมติว่าลำดับไม่มีการเพิ่มความยาวของการรัน 3 อย่างเคร่งครัดj=i+1k=j+1A[i]<A[i+1]<A[i+2]

4,3,2,1,2,3,2,1,0

ลำดับมีการเพิ่มความยาว 2 อย่างเคร่งครัดเท่านั้น (ซึ่งฉันจะเรียกลำดับคู่สั้น ๆ ) โดยคั่นด้วยความยาวที่ลดลงอย่างน้อย 2 เพื่อให้การรันเพิ่มขึ้นอย่างเข้มงวดเพื่อเป็นส่วนหนึ่งของการเพิ่มลำดับ 3 องค์ประกอบที่จะต้องมีองค์ประกอบที่ก่อนหน้านี้เช่นว่าหรือเป็นองค์ประกอบในภายหลังดังกล่าวว่า[k]A[j]<A[j+1]iA[i]<A[j]kA[j+1]<A[k]

4,3,2,2.5,1.5,0.5,1,0

กรณีที่ไม่มีทั้งและคือเมื่อแต่ละคู่ที่สั่งซื้อต่ำกว่าคู่ต่อไปทั้งหมด นี่ไม่ใช่ทั้งหมด: เมื่อทั้งคู่เชื่อมโยงกันเราจำเป็นต้องเปรียบเทียบพวกมันให้ละเอียดยิ่งขึ้นik

3,2,1,3.5,2.5,1.5,0.5, -0.5,1.25, -0.25 3,2,1,2.5,1.5,0.5,2,1,0

องค์ประกอบทางด้านซ้ายสุดของความต้องการที่เพิ่มขึ้น subsequence ที่จะมาในช่วงต้นและจะมีขนาดเล็ก องค์ประกอบต่อไปจะต้องมีขนาดใหญ่ แต่มีขนาดเล็กที่สุดเท่าที่จะสามารถที่จะหาหนึ่งในสามองค์ประกอบขนาดใหญ่kองค์ประกอบแรกที่ไม่ได้เป็นองค์ประกอบที่เล็กที่สุดในลำดับและมันก็ไม่ได้เป็นครั้งแรกที่มีองค์ประกอบที่มีขนาดใหญ่ตามมา - บางครั้งมีองค์ประกอบที่ต่ำกว่า 2 องค์ประกอบต่อไปและบางครั้งก็มีดีกว่า เหมาะสำหรับขั้นต่ำที่พบแล้วijki

2.1,3,2,1,2.5,1.5,0.5,2,1,0 1,2,0,2.5,1.5,0.5

ไปจากซ้ายไปขวาเราลังเลเลือกองค์ประกอบที่เล็กเป็นฉันหากเราพบเป็นองค์ประกอบที่มีขนาดใหญ่ที่เหมาะสมต่อไปเราเลือกคู่นี้เป็นเบื้องต้นj) หากเราพบยิ่งใหญ่กว่าเราจะชนะ สิ่งสำคัญที่ควรทราบคือตัวเลือกและตัวเลือกของเราได้รับการอัปเดตอย่างอิสระ: หากเรามีผู้สมัครและเราพบว่าเช่นนั้น ,จะเป็นผู้สมัครคนต่อไปแต่ยังคงอยู่ เฉพาะในกรณีที่เราพบเช่นที่จะi(i,j)ki(i,j)(i,j)i>jA[i]<A[i]ii(i,j)jA[j]<A[j](i,j) กลายเป็นคู่สมัครใหม่

คำชี้แจงของอัลกอริทึม

ให้ไว้ในไวยากรณ์ของ Python แต่ระวังว่าฉันยังไม่ได้ทดสอบ

def subsequence3(A):
    """Return the indices of a subsequence of length 3, or None if there is none."""
    index1 = None; value1 = None
    index2 = None; value2 = None
    for i in range(0,len(A)):
        if index1 == None or A[i] < value1:
            index1 = i; value1 = A[i]
        else if A[i] == value1: pass
        else if index2 == None:
            index2 = (index1, i); value2 = (value1, A[i])
        else if A[i] < value2[1]:
            index2[1] = i; value2[1] = A[i]
        else if A[i] > value2[1]:
            return (index2[0], index2[1], i)
    return None

ร่างหลักฐาน

index1เป็นดัชนีขั้นต่ำของส่วนหนึ่งของอาร์เรย์ที่ผ่านไปแล้ว (หากเกิดขึ้นหลายครั้งเราจะยังคงเกิดขึ้นครั้งแรก) หรือNoneก่อนที่จะประมวลผลองค์ประกอบแรก index2เก็บดัชนีของความยาวที่เพิ่มขึ้นของลำดับที่ 2 ในส่วนที่สำรวจแล้วซึ่งมีองค์ประกอบที่ใหญ่ที่สุดต่ำสุดหรือNoneหากไม่มีลำดับดังกล่าว

เมื่อreturn (index2[0], index2[1], i)วิ่งเรามีvalue2[0] < value[1](นี่คือค่าคงที่value2) และvalue[1] < A[i](ชัดเจนจากบริบท) ถ้าลูปจบลงโดยไม่ต้องเรียกคืนก่อนหน้าเช่นvalue1 == Noneในกรณีที่ไม่มีการเพิ่มความยาวของลำดับที่ 2 ให้อยู่คนเดียว 3 หรือvalue1เพิ่มการเรียงตัวของความยาวที่ 2 ซึ่งมีองค์ประกอบที่ใหญ่ที่สุดที่ต่ำที่สุด ในกรณีหลังนี้เรายิ่งมีค่าคงที่ไม่มี subsequence ที่เพิ่มขึ้นของความยาว 3 สิ้นสุดลงก่อนหน้านี้กว่าvalue1; ดังนั้นองค์ประกอบสุดท้ายของการเรียงลำดับใด ๆ ที่เพิ่มเข้ามาvalue2จะกลายเป็นการรวมกันที่เพิ่มขึ้นของความยาว 3: เนื่องจากเรายังมีค่าคงที่ที่value2ไม่ได้เป็นส่วนหนึ่งของการเพิ่มขึ้นของความยาว 3 ที่มีอยู่ในส่วนที่ ไม่มีการเรียงลำดับดังกล่าวในอาร์เรย์ทั้งหมด

การพิสูจน์ค่าคงที่ดังกล่าวถูกทิ้งไว้เป็นแบบฝึกหัดสำหรับผู้อ่าน

ความซับซ้อน

เราใช้หน่วยความจำเพิ่มเติมและสำรวจอาร์เรย์เป็นสตรีมจากซ้ายไปขวา เราดำเนินการการประมวลผลสำหรับแต่ละองค์ประกอบที่นำไปสู่การทำงานของเวลา(n)O ( 1 ) O ( n )O(1)O(1)O(n)

หลักฐานทางการ

ทิ้งไว้เป็นแบบฝึกหัดให้กับผู้อ่าน


8

O(n)O(n)

ขั้นแรกให้สำรวจอาร์เรย์จากซ้ายไปขวาเพื่อรักษาสแต็กและอาร์เรย์เสริมที่จะบอกคุณสำหรับแต่ละองค์ประกอบดัชนีขององค์ประกอบที่มากกว่าและทางด้านขวาของมัน

1

ทุกครั้งที่คุณพิจารณาองค์ประกอบใหม่ในอาร์เรย์ถ้าองค์ประกอบนั้นมากกว่าองค์ประกอบด้านบนของสแต็กคุณจะเปิดมันออกจากสแต็กและตั้งค่าองค์ประกอบอาร์เรย์อาร์เรย์ที่สอดคล้องกับด้านบนเพื่อให้มีดัชนีขององค์ประกอบใหม่ภายใต้ การพิจารณา

popping องค์ประกอบต่อไปจากสแต็กและตั้งค่าดัชนีที่สอดคล้องกันในขณะที่องค์ประกอบปัจจุบันมีค่ามากกว่า เมื่อด้านบนมีองค์ประกอบที่ไม่น้อยกว่า (หรือว่างเปล่า) ให้กดองค์ประกอบปัจจุบันลงบนสแต็กและดำเนินการกับองค์ประกอบถัดไปของอาร์เรย์แล้วทำซ้ำขั้นตอนข้างต้น

ใช้รหัสผ่านอื่น (และอีกแถวหนึ่ง aux) แต่ไปทางขวาไปซ้าย

1

O(n)

ki

รหัสเทียมสำหรับรหัสผ่านแรกอาจมีลักษณะเช่นนี้:

Stack <Pair<Elem, Index>> greats;
Elem auxArr[inputArr.Length];

for (Index i = 0; i < inputArr.Length; i++) {

    while (!greats.IsEmpty() && inputArr[i] > greats.PeekTop().Elem) {
        Pair top = greats.Pop();
        auxArr[top.Index] = i;
    }

    Pair p;
    p.Elem = inputArr[i];
    p.Index = i;

    greats.Push(p);
}

“ เนื่องจากคุณพิจารณาแต่ละองค์ประกอบของอาเรย์เท่านั้นจำนวนคงที่นี่คือเวลา O (n)” โอ้ครัม ยังไงก็เถอะฉันได้ตัดค่าคงที่หลายรอบทิ้งไปไม่ใช่ O (n) โง่มาก. ฉันขอบคุณสำหรับคำอธิบายของคุณและฉันจะพยายามอีกครั้งเพื่อแก้ไข
Christopher เสร็จ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.