สมมติว่าเราได้รับอาร์เรย์ของตัวเลขที่มี n จำนวนธรรมชาติแรก แต่องค์ประกอบหนึ่งปรากฏขึ้นสองครั้งในอาร์เรย์ ดังนั้นจำนวนองค์ประกอบทั้งหมดจึงเท่ากับ n+1 งานของเราคือเขียนฟังก์ชันที่รับอาร์เรย์และส่งกลับตัวเลขที่ปรากฏสองครั้งในเวลาเชิงเส้น
วิธีที่ 1:การใช้ Array.prototype.reduce()
นี่เป็นวิธีการที่ยุ่งยากกว่าเล็กน้อย แต่ถูกบีบอัดมากที่สุดในแง่ของการเขียนโค้ด ขั้นแรก มาดูโค้ดสำหรับมันกัน −
const arr = [1,4,8,5,6,7,9,2,3,7]; const duplicate = a => a.reduce((acc, val, ind) => val+acc- (ind+1))+a.length-1; console.log(duplicate(arr));
ในที่นี้เราได้ใช้ฟังก์ชัน reduce ซึ่งเป็นการเรียกกลับ ซึ่งทำงานเพียงครั้งเดียวสำหรับแต่ละองค์ประกอบของอาร์เรย์ ในกรณีของเรามีสามอาร์กิวเมนต์
- acc → accumulator, ค่าที่ส่งคืนใน pass ก่อนหน้า และ
- val → ค่าองค์ประกอบปัจจุบัน
- ind → ดัชนีขององค์ประกอบปัจจุบัน
ตอนนี้ มาใส่โค้ดของเรากับอาร์เรย์นี้ -
[ 2, 3, 1, 2]
เนื่องจากความยาวของอาร์เรย์นี้คือ 4 จึงควรมีฟังก์ชันเรียกกลับทั้งหมด 4 รอบ แต่เนื่องจากเราไม่ได้ระบุอาร์กิวเมนต์ initialValue ให้กับฟังก์ชัน reduce() การวนซ้ำจะเริ่มต้นจากดัชนี 1 และตัวสะสมจะถูกกำหนดค่าเริ่มต้นด้วยค่าที่ ดัชนีที่ศูนย์จึงจะมีทั้งหมด 3 รอบ
ผ่านครั้งแรก
acc = 2, val = 3, ind = 1 return value = 2+3 - (1+1) = 3
รอบที่สอง
acc = 3, val = 1, ind = 2 return value = 3+1 - (2+1) = 1
รอบที่สาม
acc = 1, val = 2, ind = 3 return value = 1+2 - (3+1) = -1
สิ้นสุดอาร์เรย์
ดังนั้น -1 จึงถูกส่งคืนจากอาร์เรย์ จากนั้น
-1 + (4-1) = -1 + 3 = 2
ได้รับการส่งคืนจากฟังก์ชันทำซ้ำ () ซึ่งเป็นผลลัพธ์ที่ถูกต้องจริง ๆ
วิธีที่ 2:Array.prototype.forEach()
ในวิธีนี้ เราวนซ้ำอาร์เรย์ หาผลรวม และลบผลรวมของตัวเลขธรรมชาติตัวแรก (n-1) ออกจากอาร์เรย์ โดยที่ n คือความยาวของอาร์เรย์ ที่เหลือคือตัวเลขที่ซ้ำกันสองครั้ง เราจึงกลับมา มัน.
ตัวอย่าง
const arr = [1,4,8,5,6,7,9,2,3,7]; const duplicate = a => { let sum = 0; const { length: n } = a; a.forEach(num => sum += num); return sum - ((n*(n-1))/2); } console.log(duplicate(arr));
ผลลัพธ์
ผลลัพธ์ในคอนโซลจะเป็น -
7