คุณจะได้รับไฟล์ซึ่งมีตัวเลขที่เป็นไปได้ทั้งหมดในสถาปัตยกรรม 32 บิต หมายเลข 4 หายไปจากไฟล์นั้น ค้นหา 4 หมายเลขที่หายไป


22

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


คำตอบ:


19

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

สำหรับฉันนั่นหมายถึงการเรียงลำดับตัวเลขและสแกนหาช่องว่าง แต่ฉันทำงานกับระบบธุรกิจและเว็บแอพ ฉันไม่ได้เล่นกับบิตและฉันไม่ต้องการให้ทีมของฉัน!

หากคุณสัมภาษณ์งานที่มีระดับต่ำและใกล้ชิดกับโลหะมากขึ้น "การเรียงลำดับ" อาจพบกับดาวว่างเปล่า พวกเขาต้องการให้คุณคิดอย่างสบายใจเกี่ยวกับบิตและอื่น ๆ คำตอบแรกของคุณควรมี "โอ้ฉันจะใช้บิตแมป" (หรืออาร์เรย์บิตหรือชุดบิต)

จากนั้นไม่ว่าจะด้วยวิธีใด - แม้ว่าคุณจะให้วิธีการ "ผิด" หากผู้สัมภาษณ์ (หรือเจ้านาย!) กดมันคุณสามารถแนะนำการปรับปรุงหรือทางเลือกอื่น ๆ โดยมุ่งเน้นไปที่ประเด็นเฉพาะของผู้จัดการ

  • RAM ที่ จำกัด อย่างรุนแรง น้อยกว่า 512MB
    จัดเรียงไว้ในตำแหน่งบนดิสก์ คุณสามารถใช้ RAM ในปริมาณมากที่สุดเพื่อปรับและ / หรือบล็อกเรียงบัฟเฟอร์
  • เวลา จำกัด?
    ใช้ RAM นั้น! O(n*log(n))เรียงลำดับอยู่แล้ว (หรือ O (n) สำหรับการจัดเรียงจำนวนเต็ม!)
  • การบำรุงรักษา?
    อะไรจะง่ายไปกว่าการจัดเรียง!
  • ไม่ได้แสดงความรู้เกี่ยวกับการตั้งค่าสถานะบิต / ฟิลด์? ( BitSet/ BitMap/ BitArray)
    โอเค ... ไปข้างหน้าและใช้ a BitArrayเพื่อตั้งค่าสถานะ "หมายเลขที่พบ" และแล้วสแกนหา0's
  • คาดการณ์ความซับซ้อน "แบบเรียลไทม์" ได้หรือไม่
    ใช้โซลูชันบิตแมป เป็นไฟล์ส่งผ่านไฟล์เดียวและอีกไฟล์ใช้ทับBitArray/BitSet(เพื่อค้นหาไฟล์0) นั่นคือO(n)ฉันคิดว่า!

หรืออะไรก็ตาม

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


ฉันไม่แน่ใจเกี่ยวกับความเป็นไปได้ในการเรียงลำดับตัวเลข 4 พันล้านหมายเลขด้วยวิธีการที่ไร้เดียงสา ไม่เคยลองเลย
Eiko

1
@Eiko อืม ... และอีกครั้งประเด็นหลักคือ ... อย่าทำสิ่งที่ซับซ้อนเกินไป ขั้นตอนแรกคือการแก้ปัญหาด้วยวิธีใดก็ตามที่คุณคิดว่าจะแก้ปัญหาแม้ว่าจะไร้เดียงสาก็ตาม ฉันไม่สามารถแม้แต่ความเครียดระดับของแห้วนายจ้างในอนาคตของคุณจะมีถ้าคุณใช้เวลากำลังทำซ้ำเพื่อให้แน่ใจว่าคุณมีกับ "ขวา" การแก้ปัญหาเมื่อธุรกิจเพียงแค่ต้องการวิธีการแก้ปัญหา พิสูจน์ว่าคุณสามารถทำได้ทั้งสองอย่าง! พิสูจน์ให้เห็นว่าคุณสามารถแก้ปัญหาได้อย่างรวดเร็วและจากนั้นระบุศักยภาพ refactoring ปัญหามูลค่าและ / หรือการเพิ่มประสิทธิภาพสำหรับเท่าที่จำเป็น
svidgen

1
@Ewan "เพราะคุณมีคำถามที่เกิดขึ้นขณะสัมภาษณ์" ไม่เหมือนกับ "มีคำตอบเดียวที่ผู้จัดการทุกคนกำลังมองหา" ... แน่นอนว่าฉันจะไม่สนใจสิ่งที่ทางแก้ให้คุณตราบใดที่คุณแสดงให้เห็นถึงความสามารถในการแก้ปัญหาและไม่แก้ปัญหาที่ฉันไม่เคยให้!
svidgen

1
คุณไม่มีจุด คำถามนี้และรูปแบบต่างๆนั้นเกิดขึ้นในหนังสือปริศนาการเขียนโปรแกรมและคำถามสัมภาษณ์ ไม่ใช่บุคคลที่สร้างคำถามขึ้นมา สิ่งที่ 32 บิตควรจะเป็นไปไม่ได้ที่จะทำโดยการติดตามตัวเลขหรือการเรียงลำดับ แค่คอมพิวเตอร์มันเร็วขึ้น / ใหญ่ขึ้นกว่าเดิมตั้งแต่เขียน
Ewan

1
@Ewan: คุณยังคงสมมติว่าอินสแตนซ์ของคำถามมีข้อ จำกัด เหมือนกับ OP OP ไม่ได้บอกว่าอัลกอริทึมของเขาต้องทำงานบนเครื่อง 32 บิตเขาไม่ได้บอกว่ามันต้องทำงานบนคอมพิวเตอร์เลยอัลกอริทึมทางความคิดอาจเหมาะสม นอกจากนี้เขายังไม่ได้ระบุว่า "ตัวเลขที่เป็นไปได้ทั้งหมด" หมายถึงอะไรเนื่องจากเป็นเลขจำนวนเต็มขนาดที่เป็นไปได้บนไมโครคอนโทรลเลอร์ขนาด 8 บิต มีข้อสันนิษฐานมากมายที่คุณต้องบอกให้
whatsisname

19

เนื่องจากเป็นไฟล์ฉันถือว่าคุณได้รับอนุญาตให้ผ่านหลายครั้งได้ ขั้นแรกสร้างอาร์เรย์จาก 256 เคาน์เตอร์วนซ้ำไฟล์และสำหรับแต่ละหมายเลขจะเพิ่มตัวนับที่ทำดัชนีเป็นไบต์แรกของตัวเลข เมื่อเสร็จแล้วเคาน์เตอร์ส่วนใหญ่ควรอยู่ที่ 2 ^ 24 แต่เคาน์เตอร์ 1 ถึง 4 ตัวควรมีค่าต่ำกว่า แต่ละดัชนีเหล่านี้แสดงถึงไบต์แรกของหนึ่งในตัวเลขที่ขาดหายไป (ถ้ามีน้อยกว่า 4 นั่นก็เพราะตัวเลขที่ขาดหายไปหลายตัวใช้ร่วมกันเป็นไบต์แรก)

สำหรับแต่ละดัชนีเหล่านี้ให้สร้างอาร์เรย์อีกจำนวน 256 ตัวนับและทำการส่งครั้งที่สองในไฟล์ เวลานี้หากไบต์แรกเป็นหนึ่งในค่าจากก่อนหน้าให้เพิ่มตัวนับในอาร์เรย์โดยยึดตามไบต์ที่สอง เมื่อเสร็จแล้วให้ค้นหาตัวนับที่ต่ำกว่า 2 ^ 16 อีกครั้งและคุณจะมีจำนวนไบต์ที่สองของตัวเลขที่หายไปโดยแต่ละคู่จะตรงกับไบต์แรก

ทำอีกครั้งสำหรับไบต์ที่สาม (โปรดสังเกตว่าคุณต้องการสูงสุด 4 อาร์เรย์ในแต่ละรอบแม้ว่าแต่ละไบต์จะสามารถตามได้สูงสุด 4 ไบต์ที่แตกต่างกัน) และสำหรับไบต์ที่สี่และคุณพบตัวเลขที่หายไปทั้งหมด

ความซับซ้อนของเวลา - ความซับซ้อนของO(n * log n)
อวกาศ - คงที่ !

แก้ไข:

ที่จริงแล้วฉันถือว่าn=2^32เป็นพารามิเตอร์ แต่จำนวนตัวเลขที่ขาดหายไปk=4ก็เป็นพารามิเตอร์เช่นกัน สมมติว่านี้หมายถึงความซับซ้อนของพื้นที่คือk<<nO(k)

ปรับปรุง:

เพียงเพื่อความสนุกสนาน (และเพราะฉันกำลังพยายามที่จะเรียนรู้สนิม) ฉันนำมาใช้มันใน Rust: https://gist.github.com/idanarye/90a925ebb2ea57de18f03f570f70ea1f ฉันเลือกที่จะเป็นตัวแทนข้อความเนื่องจากหนึ่งในนั้นจะทำงานด้วยตัวเลข ~ 2 ^ 32 ...


การเก็บตัวเลขทั้งหมดในหน่วยความจำ (สำหรับการส่งหลายครั้ง) ต้องใช้หน่วยความจำ 4 ไบต์ * 2 ^ 32 ซึ่งกำลังผลักสิ่งต่าง ๆ มีโอกาสมากขึ้นที่คุณจะทำ I / O ทั้งหมดสี่ครั้ง แต่หน่วยความจำอื่นที่ใช้มีขนาดเล็กมาก
user949300

1
@ user949300 ฉันสมมติว่าวิธีนี้อ่านไฟล์ทีละชิ้นแทนที่จะโหลดทั้งหมดลงในหน่วยความจำพร้อมกัน
Richard Tingle

"ตัวนับส่วนใหญ่ควรอยู่ที่ 2 ^ 24 แต่ตัวนับ 1 ถึง 4 ควรมีค่าที่ต่ำกว่า" - ผิด: สามารถเป็น 0 ได้โดยค่าที่หายไปทั้งหมดจะแชร์ไบต์แรก (เช่นที่สองและที่สาม) ถัดไป: คุณสร้างอาร์เรย์จำนวนเท่าใดในรอบที่สอง 256, 1 ถึง 4 ครั้ง 256, 256 ครั้ง 256? แล้วในครั้งที่สามและผ่าน?
Bernhard Hiller

3
@BernhardHiller ไฟล์มีตัวเลขที่เป็นไปได้ทั้งหมดในพื้นที่ 32- บิตประหยัดได้ 4 หมายเลข ดังนั้นไบต์แรกทั้งหมดจะเกิดขึ้นมีเพียง 1 ถึง 4 ไบต์เท่านั้นที่จะมีการเข้าชมน้อยลง
Lasse V. Karlsen

@ LasseV.Karlsen ขอบคุณตอนนี้ฉันเข้าใจอัลกอริทึมแล้ว
Bernhard Hiller

6

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

BitSet bitsetForPositives = new Bitset(2^31);  // obviously not 2^31 but you get the idea
BitSet bitsetForNegatives = new Bitset(2^31);

for (int value: valuesTheyPassInSomehow) {
  if ((value & 0x80000000) == 0)
     bitsetForPositives.set(value );
  else
     bitsetForNegatives.set(value & ~0x80000000);
}

จากนั้นใช้ BitSet.nextClearBit()เพื่อค้นหาผู้ที่หายไป

เพิ่มหมายเหตุมากในภายหลัง:

โปรดทราบว่ามีขั้นตอนวิธีการนี้มันค่อนข้างง่ายที่จะเรียกใช้เวลานานเป็นส่วนหนึ่งในแบบคู่ขนาน สมมติว่าไฟล์ต้นฉบับถูกแบ่งออกเป็นสี่ส่วนเท่า ๆ กันโดยประมาณ จัดสรร BitSets 4 คู่ (2GB, ยังจัดการได้)

  1. มีสี่กระทู้ขนานแต่ละกระบวนการหนึ่งไฟล์เป็นคู่ของ BitSets
  2. เมื่อเสร็จแล้วให้กลับไปที่เธรดเดี่ยวหรือ Bitsets (เวลาเล็กน้อย) จากนั้นโทร nextClearBit สี่ครั้ง (เช่นเวลาที่ค่อนข้างไม่แน่นอน)

ฉันคาดหวังว่า I / O จะยังคงเป็นขั้นตอน จำกัด อัตรา แต่ถ้าตัวเลขทั้งหมดอยู่ในหน่วยความจำอย่างน่าอัศจรรย์คุณสามารถเร่งความเร็วได้อย่างแท้จริง


3
@Idan Ayre วิธีนี้ต้องใช้รหัสน้อยจึงมีโอกาสน้อยกว่าในการเขียนรหัสผิดพลาด ฉันน่ารักนี่คือเวลา O (n) และไม่ถือว่า / ต้องผ่านหลายไฟล์ผ่านขนาดใหญ่ดังนั้นจึงใช้พื้นที่น้อยกว่าอัลกอริทึมที่ต้องการผ่านหลาย โปรดอธิบายสิ่งที่คุณหมายถึงโดย "โอ้ที่รัก"
user949300

2
จัดการไม่Integer.MIN_VALUEถูกต้อง คุณสามารถปกปิด bit sign แทนการปฏิเสธเพื่อแก้ไขได้
CodesInChaos

1
วิธีการที่ไร้เดียงสานี้ต้องการบิต 2 ^ 32 บิต = 4 Gib = 512 MiB สำหรับบิตเซ็ตซึ่งเป็นแรมในระดับปานกลางแม้ในระบบ 32 บิต
CodesInChaos

หากภาษาที่เลือกไม่มีตัวบิทเซ็ตในตัวให้เลียนแบบพวกมันโดยใช้อาร์เรย์ไบต์ ตัวอย่างเช่นใน C #:bool GetBit(byte[] byteArray, uint index) { var byteIndex = index >> 3; var bitInByte = index & 7; return (byteArray[byteIndex] >> bitInByte) & 1 != 0; }
CodesInChaos

1
@JoulinRouge (และ JacquesB) ดังนั้นเรายอมรับว่านี่เป็นเส้นตรงในเวลาใช้ RAM (1/2 Gig) เล็กน้อยและใช้ I / O เพียงครั้งเดียว ใช้งานได้สำหรับฉัน
user949300

5

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

C #

var bArray = new BitArray(Int32.MaxValue);

//Assume the file has 1 number per line
using (StreamReader sr = File.OpenText(fileName))
{
        string s = String.Empty;
        while ((s = sr.ReadLine()) != null)
        {
            var n = int32.Parse(s);
            bArray[n] = true;
        }
}

จากนั้นก็วนซ้ำอาร์เรย์และสำหรับค่าที่ยังคงเป็นเท็จพวกเขาไม่ได้อยู่ในไฟล์

คุณสามารถแบ่งไฟล์ออกเป็นชิ้นเล็ก ๆ แต่ฉันก็สามารถจัดสรรอาร์เรย์ขนาดสูงสุด int32 (2147483647) บนแล็ปท็อป 16.0 GB ที่ใช้ Windows 7 (64 บิต)

แม้ว่าฉันจะไม่ได้รัน 64 บิตก็ตามฉันก็สามารถจัดสรรอาร์เรย์บิตที่เล็กลงได้ ฉันจะประมวลผลไฟล์ล่วงหน้าโดยสร้างไฟล์เล็ก ๆ แต่ละไฟล์ด้วยช่วง [0-64000] [64001-128000] และหมายเลขอื่น ๆ ในนั้นที่จะเหมาะสมกับทรัพยากรด้านสิ่งแวดล้อมที่มีอยู่ ผ่านไฟล์ขนาดใหญ่และเขียนแต่ละหมายเลขไปยังไฟล์ชุดที่สอดคล้องกัน จากนั้นประมวลผลแต่ละไฟล์ที่เล็กกว่า อาจใช้เวลานานขึ้นเล็กน้อยเนื่องจากขั้นตอนการประมวลผลล่วงหน้า แต่จะได้รับการ จำกัด ทรัพยากรหากมีทรัพยากรที่ จำกัด


สิ่งนี้ดูเหมือนจะไม่จัดการกับจำนวนลบ (หรือ ints ที่ไม่ได้ลงชื่อพร้อมกับบิตสูงสุดที่ตั้งไว้ถ้านั่นคืออินพุต) หน่วยความจำสำหรับบิตเซ็ตไม่ควรเป็นปัญหาแม้แต่กับระบบ 32 บิตส่วนใหญ่
user949300

@ user949300 - ถูกต้อง ฉันไม่ได้สังเกตเห็นการใช้หน่วยความจำขนาดใหญ่เมื่ออาร์เรย์ถูกเตรียมใช้งานด้วยค่าเท็จทั้งหมด จะต้องมี BitArray รองสำหรับจำนวนลบ อาจจะเป็น bArrayNegative = BitArrary ใหม่ (Int32.MaxValue) เมื่อตัวเลขถูกอ่านมันจะถูกตรวจสอบว่าเป็นบวกหรือลบจากนั้นใส่บิตอาเรย์ที่เหมาะสม ขอบคุณสำหรับความคิดเห็น
Jon Raynor

2

เนื่องจากนี่เป็นคำถามสัมภาษณ์ฉันจะแสดงให้ผู้สัมภาษณ์เข้าใจถึงข้อ จำกัด จากนั้น "ตัวเลขที่เป็นไปได้ทั้งหมด" หมายความว่าอย่างไร จริง ๆ แล้วมันคือ 0 ... 2 <(32-1) ตามที่ทุกคนเดา? สถาปัตยกรรมแบบ 32 บิตโดยปกติสามารถทำงานกับจำนวนมากกว่า 32 บิตเท่านั้น มันเป็นเพียงเรื่องของการเป็นตัวแทนแน่นอน

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

แต่ถ้าคุณต้องการที่จะเข้าใจคำถามจริงๆว่า "ให้ไฟล์ที่มีตัวเลขทั้งหมดตั้งแต่ 0 ... 2 ^ (32-1) ยกเว้นบางอันให้ฉันหายไป" (และนี่ก็ใหญ่ถ้า !) จากนั้น มีหลายวิธีในการแก้ปัญหา

ไม่สำคัญ แต่ไม่เป็นไปได้: สำหรับแต่ละหมายเลขที่เป็นไปได้ให้สแกนไฟล์และดูว่ามีอยู่ในนั้นหรือไม่

ด้วย RAM ขนาด 512 MB และการส่งผ่านไฟล์ครั้งเดียว: ทำเครื่องหมายทุกหมายเลข (= ตั้งค่าบิตที่ดัชนีนั้น) อ่านจากไฟล์และหลังจากนั้นส่งผ่าน RAM หนึ่งครั้งและดูสิ่งที่ขาดหายไป


1
บางคำถามที่ดี แต่ไม่ว่าระบบ 32 บิตจะเป็นตัวแทนของ ints ลอยหรือ huzziwigs ก็ยังสามารถเป็นตัวแทนของค่า 2 ^ 32 ใน 32 บิต หากคำถามคือ "ใช่แล้วเราอนุญาตให้ 128 บิตยาวพิเศษ" ดังนั้นสถาปัตยกรรม 32 บิต "ข้อ จำกัด " ในคำถามก็คือการจงใจทำให้เข้าใจผิด ยังคงเป็นคำถามที่ดีที่จะถามผู้สัมภาษณ์เพราะรายละเอียดหลายอย่างทำให้เข้าใจผิดหรือเขียนไม่ดี ทางออกที่แท้จริงของคุณคือ BitSet เหมือนของฉัน
user949300

@ user949300 ใช่ - และเป็นไปไม่ได้ที่จะรู้ว่าผู้สัมภาษณ์ต้องการอะไร หากคนสุดท้ายที่พวกเขาจ้างเป็นคนที่แต่งตัวประหลาด "การแฮ็คก่อนที่จะคิด" คำตอบของคุณควรแตกต่างจากที่เป็น "ไม่มีความคิดอย่างแน่นอนเกี่ยวกับสถาปัตยกรรม" หรือ "เล่นเกมเพิ่มประสิทธิภาพ" :) ฉันเคยทำงานกับบิตเซ็ตขนาดใหญ่มาก่อน (แม้ว่าจะไม่ใช่จาวา) ดังนั้นพวกเขาจึงเข้ามาในใจของฉันตามธรรมชาติ และสามารถนำมาใช้กับหน่วยความจำต่ำได้เช่นกันหากต้องการ (bucketing) บิตเซ็ตยังแก้ปัญหา "ปัญหาการเรียงลำดับ" ในความคิดเห็นด้านบนในเวลาเชิงเส้นด้วย RAM 512 MB
Eiko

0

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

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

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

ตัวอย่างเช่นการใช้ nibble คุณมีค่าต่อไปนี้:

1010
0110
1111
0111
1101
1001
0100
0101
0001
1011
1100
1110

จำนวนบิตทั้งหมดที่ตั้งค่าในแต่ละตำแหน่งคือ:

7867

ลบออกจาก 8 (4 ^ 2/2) เราได้:

1021

ซึ่งหมายความว่ามีชุดค่าที่เป็นไปได้ 4 ค่าต่อไปนี้:

1000
0000
0011
0010

1010
0001
0010
0000

(ยกโทษให้ฉันถ้าฉันพลาดใด ๆ ฉันแค่ทำสิ่งนี้ด้วยสายตา)

แล้วดูตัวเลขเดิมอีกครั้งเราพบ 1,010 ทันทีความหมายชุดแรกคือคำตอบ


แต่คุณต้องหาตัวเลข 4 ตัวไม่ใช่หนึ่ง
freedev

@freedev คุณถูกต้อง นั่นคือสิ่งที่มันทำ ชุดของตัวเลขสี่ตัวคือตัวเลขสี่ตัว ... ในหนึ่งชุด
JimmyJames

ที่น่าสนใจ determine all the possible sets of 4 values that could give those totalsแต่คุณปัดสวะ ฉันคิดว่านี่เป็นส่วนสำคัญของวิธีแก้ปัญหาที่ขาดหายไปจากคำตอบของคุณ นอกจากนี้ยังสามารถส่งผลกระทบต่อความซับซ้อนของเวลาและพื้นที่
Allon Guralnek

@AllonGuralnek คุณพูดถูก ฉันใช้เวลาเล็กน้อยในการทำงานกับสิ่งนี้และฉันได้ประเมินค่าต่ำสุดอย่างมากมายว่าชุดตัวเลข 4 ตัวจะรวมกันเป็นจำนวนเดียวกันได้อย่างไรในกรณีที่เลวร้ายที่สุด ฉันคิดว่านี่เป็นความคิดที่กู้ได้ แต่มันค่อนข้างซับซ้อนกว่าที่ฉันวางไว้ที่นี่ ฉันจะอัปเดตพร้อมรายละเอียดในภายหลัง ฉันขอขอบคุณข้อเสนอแนะ
JimmyJames

0

สมมติว่าไฟล์ถูกเรียงลำดับตามจำนวนที่เพิ่มขึ้น:

ตรวจสอบให้แน่ใจว่ามันมีตัวเลข (2³²-4)
ตอนนี้ถ้าไฟล์เสร็จสมบูรณ์ (หรือถ้าตัวเลขที่หายไป 4 ตัวเป็น 4 ตัวสุดท้าย) การอ่านคำใด ๆ ในไฟล์ที่ตำแหน่ง N จะคืนค่าที่ตรงกัน N

ใช้การค้นหาแบบแบ่งขั้วบนตำแหน่ง [0..2³²-4-1) เพื่อค้นหาเพื่อหาหมายเลข X1 ที่ไม่ได้คาดหวังครั้งแรก
เมื่อพบว่าหมายเลขที่ขาดหายไปเป็นครั้งแรกให้ทำการค้นหา dichtotomy อีกครั้งในตำแหน่ง [X1 .. (2³²-4-1)] เพื่อค้นหาตำแหน่งที่สองที่ขาดหายไป X2: ครั้งนี้การอ่านคำที่ตำแหน่ง N ควรกลับค่าการจับคู่ N-1 หากไม่มีหมายเลขที่หายไปอีกต่อไป (เนื่องจากคุณผ่านหมายเลขที่ขาดหายไปหนึ่งรายการ)
ทำซ้ำเช่นเดียวกันสำหรับตัวเลขที่เหลือทั้งสอง ในการทำซ้ำครั้งที่สามการอ่านคำที่ตำแหน่ง N ควรกลับ N-2 และที่สี่มันควรกลับ N-3

Caveat: ฉันไม่ได้ทดสอบสิ่งนี้ แต่ฉันคิดว่ามันควรจะทำงาน :)

ตอนนี้ในชีวิตจริงฉันเห็นด้วยกับคำตอบอื่น ๆ : คำถามแรกเกี่ยวกับสภาพแวดล้อม เรามีหน่วยความจำ RAM (เท่าไหร่) เป็นไฟล์บนอุปกรณ์จัดเก็บข้อมูลการเข้าถึงโดยตรงหรือไม่นี่คือการดำเนินการครั้งเดียว (ไม่จำเป็นต้องปรับให้เหมาะสม) หรือสำคัญอย่างยิ่ง (สำคัญสำหรับแต่ละวงจร ฯลฯ
จากนั้นหาการประนีประนอมที่ยอมรับได้สำหรับบริบท อย่างน้อยนี้แสดงว่าคุณเริ่มวิเคราะห์ปัญหาก่อนค้นหาอัลกอริทึม


-2

เช่นเดียวกับคำถามมาตรฐานทั้งหมดการแก้ปัญหาคือ google พวกเขาก่อนการสัมภาษณ์

คำถามและรูปแบบนี้มีคำตอบที่ 'ถูกต้อง' ที่ชัดเจนมากซึ่งเกี่ยวข้องกับ XORing ตัวเลขทั้งหมด มันควรจะแสดงให้คุณเข้าใจดัชนีในฐานข้อมูลหรือบางสิ่งบางอย่าง ดังนั้นศูนย์คะแนนสำหรับ 'อาจทำงานได้ แต่ไม่ใช่สิ่งที่มันบอกว่าบนกระดาษ' คำตอบฉัน afriad

ในทางบวกมีชุดคำถามที่ จำกัด เหล่านี้ไม่กี่ชั่วโมงการแก้ไขจะทำให้คุณดูเหมือนอัจฉริยะ เพียงจำไว้ว่าคุณแกล้งทำมันออกมาในหัวของคุณ

แก้ไข อาห์ดูเหมือนว่า 4 มีวิธีการที่แตกต่างจากแฮคเกอร์

http://books.google.com/books?id=415loiMd_c0C&lpg=PP1&dq=muthukrishnan%20data%20stream%20algorithms&hl=el&pg=PA1#v=onepage&q=muthukrishnan%20data%20stream%20algorithms&f=false

แก้ไข Downvoters: นี่คือวิธีแก้ไขปัญหาตำราเรียน O (n) ที่ตีพิมพ์ในปัญหาที่แน่นอนที่ระบุไว้ใน OP


1
โดยเฉพาะอย่างยิ่งหนังสือที่เชื่อมโยงนี้เป็นข้อมูลเกี่ยวกับการประมวลผลสตรีม โดยเฉพาะการประมวลผลสตรีมภายในข้อ จำกัด ที่กล่าวว่าฉันจะเชื่ออย่างแน่นอนว่านี่คือต้นกำเนิดของคำถามที่ OP เห็นเพราะมันเป็นเรื่องเล็กน้อย ยิ่งกว่านั้นคุณยังไม่ได้ตอบคำถาม คุณจะมี +1 จากฉันหากคุณสามารถวางคำถามนี้อย่างมั่นใจว่าเป็นคำถาม "ดั้งเดิม" หรือ "ตั้งใจ" แล้วอธิบายวิธีแก้ปัญหา ... แต่สิ่งนี้จะไม่ตอบคำถามใด ๆ
svidgen

1
คำตอบนี้ (ในการสัมภาษณ์) เพียงแสดงให้เห็นว่าคุณอ่านหนังสือ ไม่เกี่ยวกับทักษะหรือกระบวนการคิดของคุณ และคุณจะ "google คำถามมาตรฐานทั้งหมด " ก่อนการสัมภาษณ์อย่างไร มีคำถามจำนวน จำกัด ของ "คำถามทั้งหมดที่เคยถามตอนสัมภาษณ์" ที่ฉันคิดถึงหรือไม่?
user949300

1
@ มันยังตอกย้ำความยากลำบากในการจ้างผู้สมัครที่ดี! หากคำถามที่ "ดี" เตรียมพร้อมไว้สำหรับคำถามการสัมภาษณ์ ... มันยากที่จะจ้างคนที่สามารถแก้ปัญหาธุรกิจของฉันได้จริง?
svidgen

1
@ วันที่ชัดเจนฉันทำเครื่องหมายวรรคตอนของฉันสนุก ... ไม่ว่าในกรณีใดจงจำไว้ว่าฉันยังได้รับข้อเสนองานจำนวนมากพอสมควรในวันของฉันแม้จะไม่รู้คำถามและคำตอบแบบมาตรฐานที่น่ากลัว และตอนนี้ในฐานะผู้จัดการการจ้างงานฉันสามารถสัญญากับคุณได้ว่าฉันไม่ต้องการคำตอบที่ถูกท่อง ... แม้ว่าฉันจะเข้าใจว่าผู้จัดการบางคนจะมีความต้องการที่แตกต่างกัน
svidgen

1
@Ewan ฉันควรชี้แจงอีกอย่างหนึ่งหากไม่ได้รับน้ำเสียงของฉันตามที่ตั้งใจ: คุณควรแก้ไขคำตอบของคุณเพื่อยืนยันว่าปัญหาในหนังสือที่เชื่อมโยงกับหนังสือเป็น "คำถามที่ตั้งใจทำ" แล้วตอบคำถาม! ... คุณไม่ต้องสงสัยจะมี +1 ของฉันและคนอื่น ๆ มากมายและความพึงพอใจของการช่วยให้ OP สำหรับการทำเช่นนั้น
svidgen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.