ตัวอย่างโจทย์ Leet Code
ตัวอย่างโจทย์ Backtracking
Problem 78 - Subset
https://leetcode.com/problems/subsets/description/
โจทย์แบบสั้นๆ: มี array nums ที่เก็บตัวเลขไม่ซ้ำกัน จงคืน “ทุก subset” ที่เป็นไปได้ของตัวเลข nums ออกมา
สำหรับข้อนี้ สามารถการแก้ปัญหานี้ด้วยการใช้ Backtracking (เนื่องจากต้องแตะทุก case) เราจะสร้างชุดย่อยทีละชุดโดยการเพิ่มหรือไม่เพิ่มองค์ประกอบในแต่ละขั้นตอน จากนั้นเรียกใช้ function backtrack เองอีกครั้งเพื่อสร้างชุดย่อยถัดไปออกมา
class Solution {
public:
vector<vector<int>> subsets(vector<int> &nums) {
vector<vector<int>> result;
vector<int> subset;
backtrack(result, subset, nums, 0);
return result;
}
private:
void backtrack(vector<vector<int>> &result, vector<int> &subset,
vector<int> &nums, int start) {
// เพิ่มชุดย่อยปัจจุบันลงในผลลัพธ์
result.push_back(subset);
// สร้างชุดย่อยถัดไปโดยเพิ่มหรือไม่เพิ่มองค์ประกอบ
for (int i = start; i < nums.size(); i++) {
subset.push_back(nums[i]);
backtrack(result, subset, nums, i + 1);
subset.pop_back();
}
}
};
ในการทำงาน เราจะเริ่มต้นด้วย subset ว่างเปล่า subset และส่งมันไปยัง function backtrack พร้อมกับตำแหน่งเริ่มต้นที่ 0
ภายใน function backtrack
- เราเพิ่ม subset ปัจจุบัน
subsetลงในผลลัพธ์result - จากนั้นเราวน loop ผ่านตัวที่เหลือใน Array
numsโดยเริ่มจากตำแหน่งstart- สำหรับแต่ละตัว เราเพิ่มมันลงใน
subset - เรียกใช้ function
backtrackอีกครั้งด้วยตำแหน่งเริ่มต้นถัดไป (i + 1) เพื่อสร้าง subset ถัดไป - หลังจากนั้น เราลบองค์ประกอบที่เพิ่มเข้าไปออกจาก
subsetเพื่อเตรียมสร้างชุดย่อยถัดไป
- สำหรับแต่ละตัว เราเพิ่มมันลงใน
ตัวอย่างการทำงาน เช่น
nums = [1][2][3]- เริ่มต้นด้วย subset ว่าง
[]และเพิ่มลงในผลลัพธ์ - เพิ่ม 1 ลงใน subset
[1]และเรียกใช้backtrackกับตำแหน่งเริ่มต้น 1- เพิ่ม
[1]ลงในผลลัพธ์ - เพิ่ม 2 ลงใน subset
[1][2]และเรียกใช้backtrackกับตำแหน่งเริ่มต้น 2- เพิ่ม
[1][2]ลงในผลลัพธ์ - เพิ่ม 3 ลงใน subset
[1][2][3]และเรียกใช้backtrackกับตำแหน่งเริ่มต้น 3- เพิ่ม
[1][2][3]ลงในผลลัพธ์
- เพิ่ม
- ลบ 3 ออกจาก subset
[1][2]
- เพิ่ม
- ลบ 2 ออกจาก subset
[1]
- เพิ่ม
- ไม่เพิ่มอะไรลงใน subset
[]และเรียกใช้backtrackกับตำแหน่งเริ่มต้น 1- เพิ่ม
[]ลงในผลลัพธ์ - เพิ่ม 2 ลงใน subset
[2]และเรียกใช้backtrackกับตำแหน่งเริ่มต้น 2- เพิ่ม
[2]ลงในผลลัพธ์ - เพิ่ม 3 ลงใน subset
[2][3]และเรียกใช้backtrackกับตำแหน่งเริ่มต้น 3- เพิ่ม
[2][3]ลงในผลลัพธ์
- เพิ่ม
- ลบ 3 ออกจาก subset
[2]
- เพิ่ม
- ลบ 2 ออกจาก subset
[]
- เพิ่ม
- ไม่เพิ่มอะไรลงใน subset
[]และเรียกใช้backtrackกับตำแหน่งเริ่มต้น 2- เพิ่ม
[]ลงในผลลัพธ์ - เพิ่ม 3 ลงใน subset
[3]และเรียกใช้backtrackกับตำแหน่งเริ่มต้น 3- เพิ่ม
[3]ลงในผลลัพธ์
- เพิ่ม
- เพิ่ม