แนวทางต่าง ๆ ในการแก้ไข Leetcode 205 ใน JavaScript
Isomorphic String เป็นปัญหาคลาสสิกที่ท้าทายให้เราพิจารณาว่าสตริงที่กำหนดสองสตริงมีการแมปอักขระแบบหนึ่งต่อหนึ่งหรือไม่ กล่าวอีกนัยหนึ่ง เราต้องตรวจสอบว่าเราสามารถแทนที่อักขระในสตริงหนึ่งด้วยอักขระที่เกี่ยวข้องจากสตริงอื่นในขณะที่รักษาลำดับไว้ได้หรือไม่
ในบทความนี้ เราจะสำรวจวิธีแก้ปัญหาที่มีประสิทธิภาพในการแก้ปัญหานี้ เราจะวิเคราะห์ความซับซ้อนด้านเวลาและพื้นที่ของโซลูชันของเรา ช่วยให้เราเข้าใจประสิทธิภาพและความสามารถในการปรับขนาดได้
คำชี้แจงปัญหา:
เมื่อระบุสองสตริง
s
และt
พิจารณาว่าเป็น isomorphic หรือไม่
สตริง
s
และt
สองสตริงเป็นแบบ isomorphic หากอักขระในs
สามารถแทนที่ได้เพื่อรับt
อักขระที่ปรากฏทั้งหมดจะต้องถูกแทนที่ด้วยอักขระอื่นโดยยังคงรักษาลำดับของอักขระไว้ ห้ามอักขระสองตัวจับคู่กับอักขระตัวเดียวกัน แต่อักขระหนึ่งตัวอาจจับคู่กับตัวมันเองได้
วิธีที่ 1: การเปรียบเทียบดัชนี
- เราวนซ้ำอักขระแต่ละตัวในสตริง
s
และt
และเปรียบเทียบดัชนีที่เกี่ยวข้องโดยใช้เมธอดindexOf
- หากดัชนีของอักขระปัจจุบันไม่ตรงกัน เราจะส่งคืน
false
ซึ่งบ่งชี้ว่าสตริงนั้นไม่ใช่ isomorphic - หากการวนซ้ำเสร็จสิ้นโดยไม่พบความไม่สอดคล้องใดๆ เราจะส่งคืน
true
ซึ่งบ่งชี้ว่าสตริงเป็นแบบ isomorphic
// ES6 Arrow Function const isIsomorphic = (s, t) => { if(s.length !== t.length) return false; for(let i = 0; i < s.length; i++) { if(s.indexOf(s[i]) !== t.indexOf(t[i])) { return false; } } return true; }
ความซับซ้อนของเวลา:O(N²) โดยที่ N คือความยาวของสตริง s
และ t
สำหรับอักขระแต่ละตัวใน s
โค้ดจะใช้เมธอด indexOf
เพื่อค้นหาอักขระถัดไปใน s
และ t
เมธอด indexOf
มีความซับซ้อนของเวลาเป็น O(n) ในกรณีที่เลวร้ายที่สุด และการค้นหานี้จะดำเนินการสำหรับอักขระแต่ละตัวใน s
ความซับซ้อนของอวกาศ:O(1)
ไม่ใช้โครงสร้างข้อมูลเพิ่มเติมใดๆ ที่ปรับขนาดตามขนาดอินพุต ใช้พื้นที่คงที่ในการจัดเก็บตัวแปรและค่าชั่วคราวระหว่างการทำงานของฟังก์ชันเท่านั้น
วิธีที่ 2: การแมปอักขระ
- รหัสใช้วัตถุ
Map
สองวัตถุเพื่อจัดเก็บการแมประหว่างอักขระในs
และt
- โดยวนซ้ำอักขระแต่ละตัวในสตริงและตรวจสอบว่าทั้งสองแผนที่ไม่มีการแมปสำหรับอักขระปัจจุบันหรือไม่
- ถ้าไม่เช่นนั้น ระบบจะเพิ่มการแมประหว่างอักขระในทั้งสองแมป
- หากแผนที่มีการแมปอยู่แล้ว จะตรวจสอบว่าการแมปที่มีอยู่ตรงกับอักขระปัจจุบันหรือไม่
- หากไม่ตรงกัน สตริงจะไม่เป็นแบบ isomorphic และฟังก์ชันจะส่งกลับ
false
- หากการวนซ้ำเสร็จสิ้นโดยไม่พบความไม่สอดคล้องกันใดๆ สตริงจะถือเป็น isomorphic และฟังก์ชันจะส่งกลับ
true
// ES6 Arrow Function const isIsomorphic = (s, t) => { if(s.length !== t.length) return false; const sMap = new Map(); const tMap = new Map(); for(let i = 0; i < s.length; i++) { const charS = s[i]; const charT = t[i]; if(!sMap.has(charS) && !tMap.has(charT)) { sMap.set(charS, charT); tMap.set(charT, charS); } else { if(sMap.get(charS) !== charT || tMap.get(charT) !== charS) { return false; } } } return true; }
ความซับซ้อนของเวลา:O(N)
เรากำลังวนซ้ำอักขระแต่ละตัวในสตริง s
และ t
หนึ่งครั้ง โดยดำเนินการตามเวลาคงที่ภายในลูป ดังนั้นความซับซ้อนของเวลาจึงเป็นเส้นตรง
ความซับซ้อนของอวกาศ:O(1)
ความซับซ้อนของพื้นที่ถูกกำหนดโดยขนาดของแผนที่ sMap
และ tMap
ในกรณีที่เลวร้ายที่สุด อักขระทุกตัวใน s
และ t
จะไม่ซ้ำกัน ส่งผลให้แต่ละแมปมีรายการทั้งหมด 26 รายการ (สมมติว่าเป็นตัวอักษรภาษาอังกฤษตัวพิมพ์เล็ก) ดังนั้นความซับซ้อนของพื้นที่คือ O(1) เนื่องจากจำนวนรายการสูงสุดในแผนที่ได้รับการแก้ไขโดยไม่คำนึงถึงขนาดอินพุต
แนวทางที่ 3: การทำแผนที่ความถี่
- เราใช้วัตถุความถี่สองตัว
sFreq
และtFreq
เพื่อติดตามดัชนีที่เห็นล่าสุดสำหรับอักขระแต่ละตัวในสตริงs
และt
- โค้ดจะวนซ้ำอักขระในสตริงและตรวจสอบว่าดัชนีที่เห็นล่าสุดของอักขระปัจจุบันใน
s
ตรงกับดัชนีที่เห็นล่าสุดของอักขระที่เกี่ยวข้องในt
หรือไม่ - หากไม่ตรงกัน สตริงจะไม่เป็นแบบ isomorphic และฟังก์ชันจะส่งกลับ
false
มิฉะนั้นจะอัพเดตออบเจ็กต์ความถี่ด้วยดัชนีปัจจุบัน
// ES6 Arrow Function const isIsomorphic = (s, t) => { if(s.length !== t.length) return false; let sFreq = {}, tFreq = {}; for(let i = 0; i < s.length; i++) { const charS = s[i]; const charT = t[i]; if(sFreq[charS] !== tFreq[charT]) return false; sFreq[charS] = i + 1; tFreq[charT] = i + 1; } return true; }
ความซับซ้อนของเวลา:O(N)
เราวนซ้ำอักขระของสตริงอินพุตทั้งสองหนึ่งครั้ง ดังนั้นความซับซ้อนของเวลาจึงเป็นเส้นตรง
ความซับซ้อนของอวกาศ:O(1)
ค่าคงที่ความซับซ้อนของพื้นที่เนื่องจากออบเจ็กต์ความถี่ sFreq
และ tFreq
มีขนาดคงที่สูงสุด 26 รายการ และไม่ขึ้นกับขนาดอินพุต
และคุณก็ได้แล้วทุกคน! เราได้สำรวจแนวทางที่แตกต่างกันสองแนวทาง เพิ่มประสิทธิภาพโซลูชันของเรา และหวังว่าจะได้รับความสนุกสนานไปตลอดทาง ฉันหวังว่าบทความนี้จะให้ข้อมูลเชิงลึกอันมีค่าแก่คุณและช่วยให้คุณเข้าใจแนวทางต่างๆ ในการแก้ปัญหานี้ได้ดียิ่งขึ้น ขอให้มีความสุขในการเขียนโค้ด!
ปัญหา - Leetcode 205