Эрэмбэлэгдсэн array-н хоёр захаас l, r заагчийг ойртуулж, нийлбэр нь x болох хосыг олдог арга.
Эхлээд жижиг бодлого
a = [1, 2, 4, 7, 11] дотроос нийлбэр нь 9 болох хоёр тоо хайя. l = 0, r = 4: 1 + 11 = 12 их тул r-ыг зүүн тийш. 1 + 7 = 8 бага тул l-ийг баруун тийш. 2 + 7 = 9. Олдлоо!
Хариу 2 7. Гуравхан нийлбэр бодлоо.
Энгийн аргаас санаа руу
Бүх хосыг шалгавал n(n - 1) / 2 хос, n = 10⁵ бол 5 тэрбум орчим. Удаан.
Array эрэмбэлэгдсэн гэдгийг ашиглая. Хамгийн бага a[l], хамгийн их a[r] хоёрыг нэмье. Нийлбэр их бол a[r] ямар ч тоотой нийлээд хэт их, учир нь a[l] хамгийн бага нь байсан. Тиймээс a[r]-ыг хаяж r--. Нийлбэр бага бол ижил шалтгаанаар a[l]-ийг хаяж l++. Алхам бүрт нэг тоо хасагдана.
Нэр томьёо ба тэмдэглэгээ
- l, r
- Зүүн ба баруун заагч. Хариунд орж болох тоонууд үргэлж
a[l]-ээсa[r]хүртэлх хэсэгт байна. - s
- Одоогийн нийлбэр:
a[l] + a[r]. - x
- Хайж буй нийлбэр.
- эрэмбэлэгдсэн array
- Энэ аргын гол нөхцөл. Эрэмбэгүй бол эхлээд
sortхийнэ.
Эрэмбэлэгдсэн array-гээс нийлбэр нь 10 болох хоёр тоо хайна. l зүүн захаас, r баруун захаас эхэлнэ.
- Space тоглуулах
- ←→ алхам
- −+ хурд
- a[l] ба a[r]
- Олдсон хос
- Хасагдсан
Two Pointers
Эрэмбэлэгдсэн array-гээс нийлбэр нь 10 болох хоёр тоо хайна. l зүүн захаас, r баруун захаас бие бие рүүгээ алхана.
Дараа нь юу болох вэ?
Оноо 0 / 00дараалсан зөв, хамгийн их 0
Animation нэг алхам дээр зогсоно. Дараа нь код юу хийх вэ? Таагаад оноо цуглуул! Нэвтрэх хэрэггүй, оноо чинь энэ төхөөрөмж дээр хадгалагдана.
Юунд хэрэгтэй вэ?
Эрэмбэлэгдсэн array-гээс нийлбэр нь x болох хоёр тоо олох. Бүх хосыг шалгавал n × n алхам, энэ арга n алхам хийнэ.
Яаж ажилладаг вэ?
1. l = 0 (хамгийн бага тоо), r = n − 1 (хамгийн их тоо). 2. s = a[l] + a[r]. 3. s = x бол хос олдлоо. 4. s < x бол нийлбэр бага: l баруун тийш алхана. 5. s > x бол нийлбэр их: r зүүн тийш алхана. 6. l, r уулзвал хос алга, хариу -1. Оролт: n x, дараа нь өсөх дарааллаар n тоо.
Яагаад зөв, хэр хурдан бэ?
Хариу хос нь a[i] + a[j] = x байг. l нь i-д хүрсэн үед r нь j-ээс багагүй бол нийлбэр x-ээс бага биш. Тиймээс l хөдлөхгүй, зөвхөн r багасна. Үүнтэй адилаар r нь j-д хүрсэн үед l л хөдөлнө. Тэгэхээр заагчид хариу хосыг алгасахгүй.
Алхам бүрт r - l нэгээр багасна: n-ээс цөөн алхам, хугацаа O(n). Эрэмбэлэх шаардлагатай бол O(n log n). n = 100 000 бол 100 000 хүрэхгүй алхам.
Түгээмэл алдаа
- Эрэмбэлэгдээгүй array дээр хэрэглэх. Эхлээд
sort(a, a + n). while (l <= r)гэж бичвэл нэг тоог өөртэй нь нэмж,2 · a[l] = xүед буруу хос гаргана.- Тоо 10⁹ хүртэл бол
a[l] + a[r]int-ээс хэтэрч болно.long longашигла. - Чиглэлийг андуурах: нийлбэр бага үед r-ыг багасгавал нийлбэр улам багасна.
Хязгаарын тохиолдол
- n = 1:
l < rхудал, шууд -1. - Хос байхгүй: l, r уулзаад -1.
- Ижил тоонууд
[5, 5], x = 10: хоёр өөр index тул зөв хос. - Хэд хэдэн хос байвал: аль нэгийг нь олно.
Өөрийгөө шалга
Анхдагч жишээ
1 3 4 6 8 11 14, x = 10 дээр хэдэн нийлбэр бодох вэ?Хариу харах
6: 15, 12, 9, 11, 9, 10. Хариу
4 6.Нийлбэр бага үед l-ийг нэмэх нь яагаад зөв бэ?
Хариу харах
a[l] нь хамгийн их a[r]-тай нийлсэн ч x-д хүрэхгүй. Бусад тоотой нийлбэл бүр бага. Тиймээс a[l] хэзээ ч хариунд орохгүй.
Гурван дадлага
Hint-ээ нээхээс өмнө өөрөө оролдоорой.
1.
a = [2, 3, 5, 8, 13], x = 16 үед l, r, s-ийн утгыг алхам алхмаар бич.Hint харах
Эхлээд l = 0, r = 4.
Хариу ба тайлбар
s = 2 + 13 = 15 < 16 тул l = 1. s = 3 + 13 = 16. Хариу
3 13.2.Нийлбэр нь яг x болох хос хэд байгааг тоол (тоонууд бүгд ялгаатай).
Hint харах
Хос олдсоны дараа аль заагчийг хөдөлгөх вэ?
Хариу ба тайлбар
Олдвол
cnt++хийгээдl++,r--хоёуланг нь хөдөлгөнө. Тоонууд ялгаатай тул тэр хоёр тоо өөр хосонд орохгүй.3.Эрэмбэлэгдсэн array-д нийлбэр нь x болох гурван тоо ол (3SUM), n ≤ 3000.
Hint харах
Нэг тоог тогтоогоод, үлдсэн хэсэгт Two Pointers ажиллуул.
Хариу ба тайлбар
i бүрт
l = i + 1,r = n - 1гэж эхлүүлээд нийлбэр ньx - a[i]болох хосыг Two Pointers ашиглан хайна. Нийт O(n²), n = 3000 бол 9 сая орчим алхам.
Жишээ
Оролт
7 10 1 3 4 6 8 11 14
Гаралт
4 6
Одоо өөрөө бодоод үз
Хичээл
Энэ сэдвийн хичээл удахгүй нэмэгдэнэ.