ตัวอย่างโจทย์ 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]
ลงในผลลัพธ์
- เพิ่ม
- เพิ่ม