สมมติว่าเรามีรายการของจำนวนเต็มที่เรียงลำดับตั้งแต่ 1 ถึง n ที่เริ่มจากซ้ายไปสิ้นสุดที่ด้านขวาเราต้องลบตัวเลขแรกและหมายเลขอื่น ๆ ออกทั้งหมดจนกว่าจะถึงจุดสิ้นสุดของรายการ เราจะทำซ้ำขั้นตอนก่อนหน้านี้อีกครั้ง แต่คราวนี้จากขวาไปซ้าย ลบตัวเลขที่ถูกต้องที่สุดและตัวเลขอื่นๆ ทั้งหมดออกจากตัวเลขที่เหลือ เราจะทำซ้ำขั้นตอนอีกครั้งโดยสลับจากซ้ายไปขวาและจากขวาไปซ้ายจนเหลือเลขตัวเดียว เราต้องหาตัวเลขสุดท้ายที่ยังขึ้นต้นด้วยรายการความยาว n
ดังนั้นหากอินพุตเป็น n =9 ขั้นตอนจะเป็นดังนี้ −
-
1 ,2,3 ,4,5 ,6,7 ,8,9
-
2,4 ,6,8
-
2 ,6
-
6
ดังนั้นคำตอบจะเป็น 6.
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
ซ้าย :=1 หัว :=1 ขั้นตอน :=1 rem :=n
-
ในขณะที่ rem> 1
-
ถ้า left ไม่ใช่ศูนย์หรือ rem เป็นเลขคี่ ดังนั้น head :=head + step
-
ขั้นตอน :=ขั้นตอนที่ * 2
-
ซ้าย :=ผกผันของซ้าย
-
rem :=rem / 2
-
-
กลับหัว
ตัวอย่าง (C++)
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int lastRemaining(int n) {
int head = 1;
int step = 1;
int rem = n;
int left = 1;
while(rem > 1){
if(left || rem % 2 == 1){
head += step;
}
step *= 2;
left = !left;
rem /= 2;
}
return head;
}
};
main(){
Solution ob;
cout << (ob.lastRemaining(9));
} อินพุต
9
ผลลัพธ์
6