Day-04-递归、回溯与分支 Leetcode-78, 90, 40, 22, 51, 315

//将链表中的节点push进vector
#include <stdio.h>
#include <vector>
struct ListNode {
       int val;
       ListNode* next;
       ListNode(int x) : val(x), next(NULL) {}
};
void add_to_vector(ListNode* head, std::vector<int>& vec) {
       if (head == NULL) return;
       vec.push_back(head->val);
       add_to_vector(head->next, vec);
}
int main() {
       ListNode a(1);
       ListNode b(2);
       ListNode c(3);
       ListNode d(4);
       ListNode e(5);
       a.next = &b;
       b.next = &c;
       c.next = &d;
       d.next = &e;
       std::vector<int> vec;
       add_to_vector(&a, vec);
       for (int i = 0; i < vec.size(); i++) {
              printf("[%d]", vec[i]);
       }
       printf("\n");
       return 0;
}

例一:LeetCode78




//已知一数组(其中无重复元素),求这组数组可以组成的所有子集
//不能有重复子集。
#include <stdio.h>
#include <vector>
// int main() {//非递归
//     std::vector<int> nums;
//     nums.push_back(1);
//     nums.push_back(2);
//     nums.push_back(3);
//     std::vector<int> item;
//     std::vector<std::vector<int>> result;
//     for (int i = 0; i < nums.size(); i++) {
//            item.push_back(nums[i]);
//            result.push_back(item);
//     }
//     for (int i = 0; i < nums.size(); i++) {
//            for (int j = 0; j < result[i].size(); j++) {
//                   printf("[%d]", result[i][j]);
//            }
//            printf("\n");
//     }
//     return 0;
// }
// void generate(int i, std::vector<int>& nums, std::vector<int>& item, std::vector<std::vector<int>>& result) {
//     if (i >= nums.size())return;
//     item.push_back(nums[i]);
//     result.push_back(item);
//     generate(i + 1, nums, item, result);
// }
// int main() {//递归
//     std::vector<int> nums;
//     nums.push_back(1);
//     nums.push_back(2);
//     nums.push_back(3);
//     std::vector<int> item;
//     std::vector<std::vector<int>> result;
//     generate(0, nums, item, result);
//     for (int i = 0; i < result.size(); i++) {
//            for (int j = 0; j < result[i].size(); j++) {
//                   printf("[%d]", result[i][j]);
//            }
//            printf("\n");
//     }
//     return 0;
// }
class Solution {
public:
       std::vector<std::vector<int>> subsets(std::vector<int>& nums) {
              std::vector<std::vector<int>> result;
              std::vector<int> item;
              result.push_back(item);
              generate(0, nums, item, result);
              return result;
       }
private:
       void generate(int i, std::vector<int>& nums, std::vector<int>& item, std::vector<std::vector<int>>& result) {
              if (i >= nums.size()) return;
              item.push_back(nums[i]);
              result.push_back(item);
              generate(i + 1, nums, item, result);
              item.pop_back();
              generate(i + 1, nums, item, result);
       }
};


 class Solution {
public:
       std::vector<std::vector<int>> subsets(std::vector<int>& nums) {
              std::vector<std::vector<int>> result;
              int all_set = 1 << nums.size();
              for (int i = 0; i < all_set; i++) {
                     std::vector<int> item;
                     for (int j = 0; j < nums.size(); j++) {
                           if (i & (1 << j)) {
                                  item.push_back(nums[j]);
                           }
                     }
                     result.push_back(item);
              }
              return result;
       }
};
 
int main() {
       std::vector<int> nums;
       nums.push_back(1);
       nums.push_back(2);
       nums.push_back(3);
       std::vector<std::vector<int>> result;
       Solution solve;
       result = solve.subsets(nums);
       for (int i = 0; i < result.size(); i++) {
              if (result[i].size() == 0) {
                     printf("[]");
              }
              for (int j = 0; j < result[i].size(); j++) {
                     printf("[%d]", result[i][j]);
              }
              printf("\n");
       }
       return 0;
}

例二:LeetCode90


//已知一组数(有重复元素),求这组数可以组成的所有子集
//结果中无重复子集
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <set>
class Solution {
public:
       std::vector<std::vector<int>> subsetsWithDup(std::vector<int>& nums) {
              std::vector<std::vector<int>> result;
              std::vector<int> item;
              std::set<std::vector<int>> res_set;
              std::sort(nums.begin(), nums.end());
              result.push_back(item);
              generate(0, nums, result, item, res_set);
              return result;
       }
private:
       void generate(int i, std::vector<int>& nums, std::vector<std::vector<int>>& result, std::vector < int>& item, std::set<std::vector<int>>& res_set) {
              if (i >= nums.size()) {
                     return;
              }
              item.push_back(nums[i]);
              if (res_set.find(item) == res_set.end()) {
                     result.push_back(item);
                     res_set.insert(item);
              }
              generate(i + 1, nums, result, item, res_set);
              item.pop_back();
              generate(i + 1, nums, result, item, res_set);
       }
};
int main() {
       std::vector<int> nums;
       nums.push_back(2);
       nums.push_back(1);
       nums.push_back(2);
       nums.push_back(2);
       std::vector<std::vector<int>> result;
       Solution solve;
       result = solve.subsetsWithDup(nums);
       for (int i = 0; i < result.size(); i++) {
              if (result[i].size() == 0) {
                     printf("[]");
              }
              for (int j = 0; j < result[i].size(); j++) {
                     printf("[%d]", result[i][j]);
              }
              printf("\n");
       }
       return 0;
}

例三:LeetCode40




/**已知一组数(其中有重复的元素),求这组数可以组成的所有子集中各个元素
和为整数target的子集,结果中无重复子集。
 */
#include <stdio.h>
#include <vector>
#include <set>
#include <algorithm>
class Solution {
public:
       std::vector<std::vector<int>> combinationSum2(std::vector<int>& candidates, int target) {
              std::vector<std::vector<int>> result;
              std::vector<int> item;
              std::set < std::vector<int>> res_set;
              std::sort(candidates.begin(), candidates.end());
              generate(0, candidates, result, item, res_set, 0, target);
              return result;
       }
private:
       void generate(int i, std::vector<int>& nums, std::vector<std::vector<int>>& result, std::vector<int>& item, std::set<std::vector<int>>& res_set, int sum, int target) {
              if (i >= nums.size() || sum > target) return;
              sum += nums[i];
              item.push_back(nums[i]);
              if (sum == target && res_set.find(item) == res_set.end()) {
                     result.push_back(item);
                     res_set.insert(item);
              }
              generate(i + 1, nums, result, item, res_set, sum, target);
              sum -= nums[i];
              item.pop_back();
              generate(i + 1, nums, result, item, res_set, sum, target);
       }
};
int main() {
       std::vector<int> nums;
       nums.push_back(10);
       nums.push_back(1);
       nums.push_back(2);
       nums.push_back(7);
       nums.push_back(6);
       nums.push_back(1);
       nums.push_back(5);
       std::vector<std::vector<int>> result;
       Solution solve;
       result = solve.combinationSum2(nums, 8);
       for (int i = 0; i < result.size(); i++) {
              if (result[i].size() == 0) {
                     printf("[]");
              }
              for (int j = 0; j < result[i].size(); j++) {
                     printf("[%d]", result[i][j]);
              }
              printf("\n");
       }
       return 0;
}

例四:LeetCode22


//已知有n组括号,开发一个程序,生成这n组括号的所有的合法的组合的可能。
#include <stdio.h>
#include <vector>
#include <string>
// void generate(std::string item, int n, std::vector<std::string> &result){
//     if(item.size() == 2*n){
//            result.push_back(item);
//            return;
//     }
//     generate(item+'(', n, result);
//     generate(item+')', n, result);
// }
// int main(){
//     std::vector<std::string> result;
//     generate("", 2, result);
//     for(int i=0; i<result.size(); i++){
//            printf("'%s'\n", result[i].c_str());
//     }
//     result;
// }
class Solution {
public:
       std::vector<std::string> generateParenthesis(int n) {
              std::vector<std::string> result;
              generate("", n, n, result);
              return result;
       }
private:
       void generate(std::string item, int left, int right, std::vector<std::string>& result) {
              if (left == 0 && right == 0) {
                     result.push_back(item);
                     return;
              }
              if (left > 0) {
                     generate(item + '(', left - 1, right, result);
              }
              if (left < right) {
                     generate(item + ')', left, right - 1, result);
              }
       }
};
int main() {
       Solution solve;
       std::vector<std::string> result = solve.generateParenthesis(3);
       for (int i = 0; i < result.size(); i++) {
              printf("%s\n", result[i].c_str());
       }
       return 0;
}

例五:LeetCode51




//N皇后问题
#include <stdio.h>
#include <vector>
#include <string>
class Solution {
public:
       std::vector<std::vector<std::string>> solveNQueens(int n) {
              std::vector<std::vector<std::string>> result;
              std::vector<std::vector<int>> mark;
              std::vector<std::string> location;
              for (int i = 0; i < n; i++) {
                     mark.push_back((std::vector<int>()));//先push进空的vector,为后面访问二级数组做铺垫
                     for (int j = 0; j < n; j++) {
                           mark[i].push_back(0);//初始化mark为0
                     }
                     location.push_back("");//push进空字符串
                     location[i].append(n, '.');//将字符串初始为n个.
              }
              generate(0, n, location, result, mark);
              return result;
       }
private:
       void put_down_the_queen(int x, int y, std::vector<std::vector<int>>& mark) {
              static const int dx[] = { -1, 1, 0, 0, -1, -1, 1, 1 };//方向数组
              static const int dy[] = { 0, 0, -1, 1, -1, 1, -1, 1 };
              mark[x][y] = 1;
              for (int i = 1; i < mark.size(); i++) {
                     for (int j = 0; j < 8; j++) {
                           int new_x = x + i * dx[j];
                           int new_y = y + i * dy[j];
                           if (new_x >= 0 && new_x < mark.size() && new_y >= 0 && new_y < mark.size()) {
                                  mark[new_x][new_y] = 1;
                           }
                     }
              }
       }
       void generate(int k, int n, std::vector<std::string>& location, std::vector<std::vector<std::string>>& result, std::vector<std::vector<int>>& mark) {
              if (k == n) {
                     result.push_back(location);
                     return;
              }
              for (int i = 0; i < n; i++) {
                     if (mark[k][i] == 0) {
                           std::vector<std::vector<int>> tmp_mark = mark;
                           location[k][i] = 'Q';
                           put_down_the_queen(k, i, mark);
                           generate(k + 1, n, location, result, mark);
                           mark = tmp_mark;
                           location[k][i] = '.';
                     }
              }
       }
};
int main() {
       std::vector<std::vector<std::string>> result;
       Solution solve;
       result = solve.solveNQueens(4);
       for (int i = 0; i < result.size(); i++) {
              printf("i = %d\n", i);
              for (int j = 0; j < result[i].size(); j++) {
                     printf("%s\n", result[i][j].c_str());
              }
       }
       return 0;
}

例六:LeetCode315












//已知数组nums,求新数组count,count[i]代表了在nums[i]右侧且比nums[i]小的个数
#include <stdlib.h>
#include <vector>
#include <assert.h>
#include <algorithm>
#include <time.h>
// int main() {
//     std::vector<int> vec1;
//     std::vector<int> vec2;
//     srand(time(NULL));
//     for (int i = 0; i < 10000; i++) {
//            int num = (rand() * rand()) % 100003;
//            vec1.push_back(num);
//            vec2.push_back(num);
//     }
//     merge_sort(vec1);
//     std::sort(vec2.begin(), vec2.end());
//     assert(vec1.size() == vec2.size());//断言:测试是否符合条件,否则终止程序
//     for (int i = 0; i < vec1.size(); i++) {
//            assert(vec1[i] == vec2[i]);
//     }
//     return 0;
// }
class Solution {
public:
       std::vector<int> countSmaller(std::vector<int>& nums) {
              std::vector<std::pair<int, int>> vec;
              std::vector<int> count;
              for (int i = 0; i < nums.size(); i++) {
                     vec.push_back(std::make_pair(nums[i], i));
                     count.push_back(0);
              }
              merge_sort(vec, count);
              return count;
       }
private:
       //归并两个已排序数组
       void merge_sort_two_vec(std::vector<std::pair<int, int>>& sub_vec1, std::vector<std::pair<int, int>>& sub_vec2,
              std::vector<std::pair<int, int>>& vec, std::vector<int>& count) {
              int i = 0;
              int j = 0;
              while (i < sub_vec1.size() && j < sub_vec2.size()) {
                     if (sub_vec1[i].first <= sub_vec2[j].first) {
                           count[sub_vec1[i].second] += j;
                           vec.push_back(sub_vec1[i]);
                           i++;
                     }
                     else {
                           vec.push_back(sub_vec2[j]);
                           j++;
                     }
              }
              for (; i < sub_vec1.size(); i++) {
                     count[sub_vec1[i].second] += j;
                     vec.push_back(sub_vec1[i]);
              }
              for (; j < sub_vec2.size(); j++) {
                     vec.push_back(sub_vec2[j]);
              }
       }
       void merge_sort(std::vector<std::pair<int, int>>& vec, std::vector<int>& count) {//归并排序
              if (vec.size() < 2) {
                     return;
              }
              int mid = vec.size() / 2;
              std::vector<std::pair<int, int>> sub_vec1;
              std::vector<std::pair<int, int>> sub_vec2;
              for (int i = 0; i < mid; i++) {
                     sub_vec1.push_back(vec[i]);
              }
              for (int i = mid; i < vec.size(); i++) {
                     sub_vec2.push_back(vec[i]);
              }
              merge_sort(sub_vec1, count);
              merge_sort(sub_vec2, count);
              vec.clear();
              merge_sort_two_vec(sub_vec1, sub_vec2, vec, count);
       }
};
int main() {
       int test[] = { 5, -7, 9, 1, 3, 5, -2, 1 };
       std::vector<int> nums;
       for (int i = 0; i < 8; i++) {
              nums.push_back(test[i]);
       }
       Solution solve;
       std::vector<int> result = solve.countSmaller(nums);
       for (int i = 0; i < result.size(); i++) {
              printf("[%d]", result[i]);
       }
       printf("\n");
       return 0;
}

猜你喜欢

转载自www.cnblogs.com/lihello/p/11520881.html
315