ดังนั้นคุณจะมี โล่งใจ เหนื่อย. ในที่สุดคุณก็ได้พบกับวิธีการแก้ปัญหาการเข้ารหัสคำถามที่ผู้สัมภาษณ์ถามคุณ บางทีคุณอาจเขียนมันลงบนไวท์บอร์ดทีละบรรทัด และคุณทำช่วงเวลาที่ดี! คุณเข้าประชุมเพียง 20 นาที ผู้สัมภาษณ์ของคุณต้องประทับใจ
ขวา?
“ มันจะใช้งานได้ แต่ความคิดใด ๆ เกี่ยวกับวิธีการทำอย่างมีประสิทธิภาพมากขึ้น?”
หัวใจของคุณจม คุณคิดว่าคุณทำเสร็จแล้วด้วยส่วนการออกแบบอัลกอริทึมหากิน! คุณพยายามคิดหาวิธีในการแก้ปัญหามากกว่านี้ แต่สิ่งที่คุณคิดได้ก็คือวิธีการเดียวที่คุณได้คิดมาแล้ว
เรื่องนี้เกิดขึ้นกับเกือบทุกคน และไม่ใช่เพราะพวกเขาโง่ เป็นเพราะคนส่วนใหญ่ไม่มีวิธีในการปรับปรุงประสิทธิภาพของอัลกอริทึมของพวกเขา
แต่ความจริงก็คือมีมากมาย ครั้งต่อไปที่คุณนิ่งงันลองใช้วิธีการทั่วไปทั้งสามนี้
1. ใช้ Hash Map
ถูกตัอง. Hash maps / อาเรย์เชื่อมโยง / พจนานุกรม (มีหลายชื่อขึ้นอยู่กับภาษาการเขียนโปรแกรมที่คุณใช้) มีความสามารถที่จะลดการใช้งานอัลกอริทึมลง
ตัวอย่างเช่นสมมติว่าคำถามคือหาตัวเลขที่ซ้ำกันมากที่สุดในอาร์เรย์ของตัวเลข
ความคิดแรกของคุณอาจเป็นการกระโดดเข้าไปในลูป สำหรับตัวเลขแต่ละตัวของเราให้หาจำนวนและดูว่ามันเป็นตัวเลขที่ใหญ่ที่สุดหรือไม่ เราจะได้รับการนับสำหรับแต่ละหมายเลขได้อย่างไร วนรอบอาร์เรย์นับจำนวนครั้งที่มันเกิดขึ้น! เรากำลังพูดถึงลูปซ้อนกันสองวง ใน pseudocode:
def get_mode (nums): max_count = 0 โหมด = null สำหรับ potential_mode ใน nums: count = 0 สำหรับตัวเลขใน our_array: count + = 1 ถ้า count> = max_count: โหมด = potential_mode max_count = โหมดส่งกลับนับ
ตอนนี้เรากำลังวนรอบอาร์เรย์ทั้งหมดของเราหนึ่งครั้งสำหรับแต่ละรายการในอาร์เรย์ - แต่เราทำได้ดีกว่า ในสัญกรณ์ O ใหญ่นั่นคือเวลา O (n 2 ) ทั้งหมด
หากเราเก็บค่าการนับของเราไว้ในแผนที่แฮช (หมายเลขการจับคู่กับจำนวน) เราสามารถแก้ปัญหาได้ในเวลาเพียงหนึ่งผ่านอาร์เรย์ (O (n) เวลา!):
def get_mode (จำนวน): max_count = 0 โหมด = นับเป็นโมฆะ = ใหม่ HashMap เริ่มต้นแต่ละค่าที่ 0 สำหรับ potential_mode ในจำนวน nums: นับ + = 1 ถ้านับ> max_count: โหมด = potential_mode max_count = นับกลับโหมด
เร็วขึ้นมาก!
2. ใช้การจัดการบิต
นี้จะทำให้คุณแตกต่างจากชุด มันไม่ได้ใช้กับปัญหาทุกอย่าง แต่ถ้าคุณเก็บมันไว้ในกระเป๋าหลังของคุณและจับมันในเวลาที่เหมาะสมคุณจะดูเหมือนร็อคสตาร์
นี่คือตัวอย่าง: สมมติว่าเรามีอาร์เรย์ของจำนวนที่ทุก ๆ หมายเลขปรากฏขึ้นสองครั้งยกเว้นหนึ่งหมายเลขที่เกิดขึ้นเพียงครั้งเดียว เรากำลังเขียนฟังก์ชั่นเพื่อค้นหาจำนวนที่อ้างว้างและไม่ซ้ำ
สัญชาตญาณแรกของคุณอาจจะใช้แผนที่แฮชเนื่องจากเราเพิ่งพูดถึงมัน นั่นเป็นสัญชาตญาณที่ดีที่จะมี! และมันจะใช้ได้กับอันนี้ เราสามารถสร้างแผนที่ "การนับ" ที่คล้ายกันมากและใช้เพื่อดูว่าตัวเลขใดที่ลงท้ายด้วยการนับ 1
แต่มีวิธีที่ดีกว่า หากคุณคุ้นเคยกับการจัดการบิตคุณอาจคุ้นเคยกับ XOR สิ่งหนึ่งที่พิเศษเกี่ยวกับแฮคเกอร์คือถ้าคุณแฮคจำนวนด้วยตัวเองบิต "ยกเลิก" เป็น 0 สำหรับปัญหานี้ถ้าเราแฮคเกอร์ทุกตัวในอาร์เรย์ด้วยกันเราจะเหลือจำนวนหนึ่งที่ไม่ได้ ไม่ต้องยกเลิก:
def find_unrepeated (nums): unrepeated = 0 สำหรับ num ใน nums: unrepeated = unrepeated XOR num num return unrepeated
3. เริ่มจากล่างขึ้นบน
เขียนฟังก์ชั่นที่ส่งออกหมายเลข“ nth” Fibonacci โดยระบุตัวเลข n คนนี้คลาสสิกและมันยืมตัวเองอย่างมากที่จะเรียกซ้ำ:
def fib (n): ถ้า n เป็น 0 หรือ 1: return 1 return fib (n-1) + fib (n-2)
แต่คำตอบแบบง่ายๆไม่ได้เป็นคำตอบเดียว! คิดให้รอบคอบเกี่ยวกับสิ่งที่ฟังก์ชั่นนี้ทำ สมมติว่า n คือ 5 เพื่อให้ได้คำตอบมันจะโทรหา fib (4) ซ้ำ ๆ (3) ทีนี้การเรียกร้องให้กำลังใจ (4) ทำอะไร? มันเรียกว่าตอแหล (3) และตอแหล (2) แต่เราเพิ่งบอกว่าเรามีการโทรไปป่วน (3)! ฟังก์ชั่นการเรียกซ้ำที่น่ารักนี้ทำงานได้ซ้ำหลายครั้ง ต้นทุนเวลาทั้งหมดกลายเป็น O (2 n ) ไม่ดี - แย่กว่า O (n 2 )
แทนที่จะไปจาก n ซ้ำลงไป 1 เรามา“ bottom-up” จาก 1 ถึง n สิ่งนี้ช่วยให้เราข้ามการสอบถามซ้ำ:
def fib (n): ก่อนหน้า = 0 ก่อนหน้านี้ก่อนหน้า = 1 สำหรับฉันในช่วง 1 ถึง n: ปัจจุบัน = ก่อนหน้านี้ + ก่อนหน้านี้ก่อนหน้านี้ก่อนหน้าก่อนหน้า = ก่อนหน้านี้ = ปัจจุบันกลับมาปัจจุบัน
รหัสยาวขึ้น แต่ก็มีประสิทธิภาพมากกว่านี้มาก! ลงเวลา O (n) ในฐานะโบนัสเพิ่มเติมที่มีอัลกอริทึมแบบเรียกซ้ำเราช่วยประหยัดพื้นที่ การเรียกซ้ำทั้งหมดเหล่านี้สร้างขึ้นใน call stack ซึ่งตั้งอยู่ในหน่วยความจำและนับรวมกับต้นทุนพื้นที่ของเรา ฟังก์ชันเรียกซ้ำของเรามีค่าใช้จ่ายพื้นที่ O (n) แต่อันนี้ซ้ำใช้พื้นที่ O (1)
ครั้งต่อไปที่ผู้สัมภาษณ์ขอให้คุณปรับปรุงประสิทธิภาพของการแก้ปัญหาลองทำตามกลยุทธ์เหล่านี้และดูว่าพวกเขาช่วยได้หรือไม่ ด้วยการฝึกฝนอย่างเพียงพอคุณอาจพบว่าตัวเองกระโดดตรงไปยังโซลูชันที่ได้รับการปรับปรุงให้ดีที่สุด และนั่นคือสิ่งที่ดี ไม่ได้หมายความว่าคุณจะกลายเป็นผู้สัมภาษณ์ที่ดีกว่า แต่นั่นหมายความว่าคุณจะกลายเป็นวิศวกรที่ดีขึ้น




