image.png

思路:回溯 + 剪枝

  • cur_index就是树的深度
  • vis数组的本质目的就是为了剪枝操作(禁止重复的数字出现)
  • 如何进行回溯?vis[i] = false; cur_permute.pop_back();

最关键之处在于:脑子里面要有树的图形
image.png

代码:

  1. class Solution {
  2. public:
  3. void traceBack(vector<vector<int>> &res, vector<int> &cur_permute, int cur_index, int full_len, vector<bool> &vis, vector<int> &nums) {
  4. if (cur_index == full_len) {
  5. res.push_back(cur_permute);
  6. return;
  7. }
  8. for (int i = 0; i < full_len; ++i) {
  9. if (!vis[i]) {
  10. cur_permute.push_back(nums[i]);
  11. vis[i] = true;
  12. // cur_index 就是树的深度
  13. traceBack(res, cur_permute, cur_index + 1, full_len, vis, nums);
  14. // traceBack(res, cur_permute, i + 1, full_len, vis, nums); 是有问题的
  15. // i + 1 == 3,说明 i == 2,也就是树上以3结尾的。但是实际上我们需要层次是3的树
  16. // 回溯操作
  17. vis[i] = false;
  18. cur_permute.pop_back();
  19. }
  20. }
  21. }
  22. vector<vector<int>> permute(vector<int>& nums) {
  23. vector<vector<int>> res;
  24. vector<int> cur_permute;
  25. vector<bool> vis(nums.size() + 1, false);
  26. traceBack(res, cur_permute, 0, nums.size(), vis, nums);
  27. return res;
  28. }
  29. };