From 03a1b77a30baea085f724a118c778f38031442aa Mon Sep 17 00:00:00 2001 From: liujj Date: Tue, 9 Aug 2022 07:29:33 +0800 Subject: [PATCH] [IM]: leetcode --- ...4\345\214\205\351\227\256\351\242\230.cpp" | 147 ++++++++++++++++++ .../03.7.8\345\210\267\351\242\230/120.cpp" | 29 ++++ .../03.7.8\345\210\267\351\242\230/343.cpp" | 69 ++++++++ .../03.7.8\345\210\267\351\242\230/37.cpp" | 100 ++++++++++++ .../03.7.8\345\210\267\351\242\230/39.cpp" | 66 ++++++++ .../03.7.8\345\210\267\351\242\230/392.cpp" | 59 +++++++ .../03.7.8\345\210\267\351\242\230/40.cpp" | 66 ++++++++ .../03.7.8\345\210\267\351\242\230/64.cpp" | 57 +++++++ .../03.7.8\345\210\267\351\242\230/91.cpp" | 37 +++++ 9 files changed, 630 insertions(+) create mode 100644 "03.code/08.leetcode/03.7.8\345\210\267\351\242\230/00.0-1\350\203\214\345\214\205\351\227\256\351\242\230.cpp" create mode 100644 "03.code/08.leetcode/03.7.8\345\210\267\351\242\230/120.cpp" create mode 100644 "03.code/08.leetcode/03.7.8\345\210\267\351\242\230/343.cpp" create mode 100644 "03.code/08.leetcode/03.7.8\345\210\267\351\242\230/37.cpp" create mode 100644 "03.code/08.leetcode/03.7.8\345\210\267\351\242\230/39.cpp" create mode 100644 "03.code/08.leetcode/03.7.8\345\210\267\351\242\230/392.cpp" create mode 100644 "03.code/08.leetcode/03.7.8\345\210\267\351\242\230/40.cpp" create mode 100644 "03.code/08.leetcode/03.7.8\345\210\267\351\242\230/64.cpp" create mode 100644 "03.code/08.leetcode/03.7.8\345\210\267\351\242\230/91.cpp" diff --git "a/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/00.0-1\350\203\214\345\214\205\351\227\256\351\242\230.cpp" "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/00.0-1\350\203\214\345\214\205\351\227\256\351\242\230.cpp" new file mode 100644 index 0000000..dd945f8 --- /dev/null +++ "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/00.0-1\350\203\214\345\214\205\351\227\256\351\242\230.cpp" @@ -0,0 +1,147 @@ +#include +#include +#include +using namespace std; + +// 有一个背包,他的容量为C(Capacity)。现在又n种不同的物品,编号为0....n - 1 ,其中每一件物品的重量为w(i),价值为v(i).问可以向这个背包中盛放哪些物品,使得在不超过背包容量的基础上,物品的总价值最大 +// 暴力解法:每一件物品都可以放进背包,也可以不放进去 +// 动态规划: +// 状态定义: +// F(n,C) :将n个物品放进容量为C的背包,使得价值最大 +// F(i, c) = F(i - 1, c) // i不放入背包 +// = v(i) + F(i - 1, c- W(i)) // i放入背包 +class Solution +{ +private: + // 用[0 ... index]的物品,填充容积为C的背包的最大价值 + int bestValue(const vector &w, const vector v, int index, int c) + { + if (index < 0 || c <= 0) + { + return 0; + } + + int res = bestValue(w, v, index - 1, c); + if (c >= w[index]) + { + res = max(res, v[index] + bestValue(w, v, index - 1, c - w[index])); + } + + return res; + } + + // 动态规划 + 记忆化搜索 + vector> memo; // + int bestValue2(const vector &w, const vector v, int index, int c) + { + if (index < 0 || c <= 0) + { + return 0; + } + + if (memo[index][c] != -1) + { + return memo[index][c]; + } + + int res = bestValue(w, v, index - 1, c); + if (c >= w[index]) + { + res = max(res, v[index] + bestValue(w, v, index - 1, c - w[index])); + } + + memo[index][c] = res; + + return res; + } +public: + int knapspack01(const vector &w, const vector &v, int c) + { + int n = w.size(); + return bestValue(w, v, n - 1, c); + } + int knapspack02(const vector &w, const vector &v, int c) + { + int n = w.size(); + + memo = vector> (n, vector(c + 1, -1)); // n * C + 1 + return bestValue2(w, v, n - 1, c); + } + int knapspack03(const vector &w, const vector &v, int c) + { + int n = w.size(); + if (0 == n) + { + return 0; + } + vector> memo(n, vector(c + 1, -1)); + + // 先考虑0号物品 + for (int j = 0; j <= c; ++j) + { + memo[0][j] = ( j >= w[0] ? v[0] : 0); + } + + for (int i = 1; i < n; ++i) + { + for (int j = 0; j <= c; ++j) + { + memo[i][j] = memo[i - 1][j]; + if (j >= w[i]) + { + memo[i][j] = max( memo[i][j], v[i] + memo[i - 1][j - w[i]]); + } + } + } + + return memo[n - 1][c]; + } + + int knapspack04(const vector &w, const vector &v, int c) + { + int n = w.size(); + if (0 == n) + { + return 0; + } + vector> memo(2, vector(c + 1, -1)); + + // 先考虑0号物品 + for (int j = 0; j <= c; ++j) + { + memo[0][j] = ( j >= w[0] ? v[0] : 0); + } + + for (int i = 1; i < n; ++i) + { + for (int j = 0; j <= c; ++j) + { + memo[i % 2][j] = memo[(i - 1) % 2][j]; + if (j >= w[i]) + { + memo[i % 2][j] = max( memo[i % 2][j], v[i] + memo[(i - 1) % 2][j - w[i]]); + } + } + } + + return memo[(n - 1) % 2][c]; + } + +}; + + +int main() { + + vector w = {1, 2, 3}; + vector v = {6, 10, 12}; + int c = 5; + + Solution sol; + cout << sol.knapspack01(w, v, c) << endl; + cout << sol.knapspack02(w, v, c) << endl; + cout << sol.knapspack03(w, v, c) << endl; + cout << sol.knapspack04(w, v, c) << endl; + + + return 0; +} diff --git "a/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/120.cpp" "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/120.cpp" new file mode 100644 index 0000000..3aa87e8 --- /dev/null +++ "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/120.cpp" @@ -0,0 +1,29 @@ +#include +#include +using namespace std; + +class Solution { +public: + int min(vector> &triangle) + { + size_t size = triangle.size(); + for (int i = triangle.size(); i > 0; --i) + { + for (int j = 0; j < triangle[size].size(); ++j) + { + triangle[size][j] = min(triangle[i][j - 1], triangle[i][j]); + } + } + + return 0; + } + int minimumTotal(vector>& triangle) { + + } +}; + +int main() +{ + + return 0; +} \ No newline at end of file diff --git "a/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/343.cpp" "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/343.cpp" new file mode 100644 index 0000000..915daa3 --- /dev/null +++ "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/343.cpp" @@ -0,0 +1,69 @@ +#include +#include +using namespace std; + +int integerBreak(int n) { + vector dp(n + 1, 0); + dp[1] = 1; + + for (int i = 0; i < n + 1; ++i) + { + for (int j = i - 1; j >= 1; --j) + { + dp[i] = max(dp[i], dp[j] * (i - j)); + cout << "max1:" << dp[i] << ", " << dp[j] * (i - j) << endl; + dp[i] = max(dp[i], j * (i - j)); + cout << "max2:" << dp[i] << ", " << j * (i - j) << endl; + } + cout << endl; + } + + return dp[n]; +} + +/** + * 1. 确定dp数组下标含义 分拆数字i,可以得到的最大乘积为dp[i]; + * 2. 递推公式 dp[i] = max(dp[i], (i - j) * j, dp[i - j] * j); + * 3. 初始化 dp[2] = 1; + * 4. 遍历顺序 从前向后遍历就可以; + * 5. 推导结果; + */ +int integerBreak2(int n) +{ + /* 定义dp数组 */ + vector dp(n + 1, 0); + /* dp数组初始化 */ + dp[2] = 1; + /* 从前向后遍历 */ + cout << "dp[i] " << ",dp[i - j] * j" << ",((i - j) * j)" << endl; + for (int i = 3; i <= n ; i++) + { + /* j遍历到小于i的值 */ + for (int j = 1; j < i - 1; j++) + { + cout << dp[i] << " "; + dp[i] = max(dp[i], dp[i - j] * j); + cout << dp[i - j] * j << " "; + dp[i] = max(dp[i], ((i - j) * j)); + cout << ((i - j) * j) << " | "; + } + cout << "dp[" << i << "]->" << dp[i] << endl; + } + return dp[n]; +} + +int integerBreak3(int n) +{ + if (2 == n) + { + return 1; + } + + return 0; +} + +int main() { + + cout << integerBreak2(10) << endl; + return 0; +} diff --git "a/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/37.cpp" "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/37.cpp" new file mode 100644 index 0000000..68c84cd --- /dev/null +++ "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/37.cpp" @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +vector> col = vector>(9, vector(9, false)); + +void print(vector>& v)//, vector> &col) +{ + for_each(v.begin(), v.end(), + [&](vector &w){ + for_each(w.begin(), w.end(), [&](char &val){ cout << val << ' '; }); + cout << endl; + }); + + // for_each(col.begin(), col.end(), + // [&](vector &w){ + // for_each(w.begin(), w.end(), [&](bool val){ cout << val << ' '; }); + // cout << endl; + // }); +} + +int c = 0; + +vector> ans; + +void dfs(int x, int y, vector &v, vector &row) +{ + if (y == v.size()) + { + ans.push_back(row); + return ; + } + + row.push_back(v[y]); + if ('.' == row[y]) + { + char tmp; + for (int j = 0; j < col[x].size(); ++j) + { + if (!col[x][j]) + { + tmp = j + '0'; + } + } + col[x][tmp - '0'] = true; + row[y] = tmp; + } + dfs(x, y + 1, v, row); + +} + +void solveSudoku(vector>& v) +{ + for_each(v.begin(), v.end(), + [&](vector &w){ + for_each(w.begin(), w.end(), + [&](char &val){ + if ('.' != val) + { + col[c][val - '0'] = true; + } + }); + ++c; + }); + + + print(v);//, col); +} + +int main() +{ + vector> v = { + {'5','3','.','.','7','.','.','.','.'},{'6','.','.','1','9','5','.','.','.'},{'.','9','8','.','.','.','.','6','.'}, + {'8','.','.','.','6','.','.','.','3'},{'4','.','.','8','.','3','.','.','1'},{'7','.','.','.','2','.','.','.','6'}, + {'.','6','.','.','.','.','2','8','.'},{'.','.','.','4','1','9','.','.','5'},{'.','.','.','.','8','.','.','7','9'} + }; + + solveSudoku(v); + + // char c = 2 + '0'; + // cout << c << endl; + vector v1 = {'5','3','.','.','7','.','.','.','.'}; + vector row; + dfs(0, 0, v1, row); + cout << "----" << endl; + print(ans); + // for_each(v1.begin(), v1.end(), [](char &v) { cout << v << " ";}); + + + return 0; +} diff --git "a/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/39.cpp" "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/39.cpp" new file mode 100644 index 0000000..20bb538 --- /dev/null +++ "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/39.cpp" @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +vector path; +vector> ans; + +void dfs(int target, int index, vector &nums) +{ + if (target < 0) + { + return ; + } + + if (0 == target) + { + ans.push_back(path); + return ; + } + + for (int i = index; i < nums.size(); ++i) + { + if (nums[i] <= target) + { + path.push_back(nums[i]); + cout << "push: " << nums[i] << " "; + dfs(target - nums[i], i, nums); + path.pop_back(); + cout << "pop" << endl; + } + } + return ; +} + +vector> combinationSum(vector& candidates, int target) { + dfs(target, 0, candidates); + return ans; +} + +int main() { + + vector v = {2,3,6,7}; + + vector> ans = combinationSum(v, 7); + + for (auto i : ans) + { + for (auto j : i) + { + cout << j << " "; + } + cout << endl; + } + cout << endl; + + return 0; +} diff --git "a/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/392.cpp" "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/392.cpp" new file mode 100644 index 0000000..0af6f16 --- /dev/null +++ "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/392.cpp" @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +class Solution { +public: + bool isSubsequence(string s, string t) + { + int l = 0; + int r = t.size() - 1; + + int sl = 0; + int sr = s.size() - 1; + cout << "ans : " << r << ", "<< sr << endl; + while (l < r && sl <= sr) + { + // cout << l << ", " << r << endl; + // cout << sl << ", " << sr << endl; + if (s[sl] == t[l]) + { + cout << "l:" << s[sl] << "," << t[l] << endl; + ++sl; + } + if (s[sr] == t[r]) + { + cout << sr << ", " << sr << endl; + cout << "r:" << s[sr] << "," << t[r] << endl; + --sr; + } + --r; + ++l; + } + // cout << + if (s[sl] == t[l]) ++sl; + // cout << s[sl] <<"," << t[l] << endl; + // cout << sl << "," << sr << endl; + return sl > sr; + + } +}; + +int main() { + + Solution s; + // cout << s.isSubsequence("axc", "ahbgdc") << endl; + cout << (s.isSubsequence("b", +"abc") == 1 ? "true" : "false") << endl; + + return 0; +} diff --git "a/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/40.cpp" "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/40.cpp" new file mode 100644 index 0000000..59187e8 --- /dev/null +++ "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/40.cpp" @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +vector> result; +vector path; +void backtracking(vector& candidates, int target, int sum, int startIndex, vector& used) { + if (sum == target) { + result.push_back(path); + return; + } + for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) { + // used[i - 1] == true,说明同一树枝candidates[i - 1]使用过 + // used[i - 1] == false,说明同一树层candidates[i - 1]使用过 + // 要对同一树层使用过的元素进行跳过 + if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) { + continue; + } + sum += candidates[i]; + path.push_back(candidates[i]); + used[i] = true; + backtracking(candidates, target, sum, i + 1, used); // 和39.组合总和的区别1,这里是i+1,每个数字在每个组合中只能使用一次 + used[i] = false; + sum -= candidates[i]; + path.pop_back(); + } +} + +vector> combinationSum2(vector& candidates, int target) { + vector used(candidates.size(), false); + path.clear(); + result.clear(); + // 首先把给candidates排序,让其相同的元素都挨在一起。 + sort(candidates.begin(), candidates.end()); + backtracking(candidates, target, 0, 0, used); + return result; +} + +int main() { + + vector v = {2,3,6,7};//{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; + // cout << v.size() << endl; + // return 0; + vector> ans = combinationSum2(v, 7); + + for (auto i : ans) + { + for (auto j : i) + { + cout << j << " "; + } + cout << endl; + } + cout << endl; + + return 0; +} diff --git "a/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/64.cpp" "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/64.cpp" new file mode 100644 index 0000000..230a0a6 --- /dev/null +++ "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/64.cpp" @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + + +int minPathSum(vector>& grid) { + if (grid.size() == 0) + { + return 0; + } + + // 从gird[grid.size() - 1][grid[0].size() - 1]往前看 + + // 先解决没有左边和上边的网格 + for (int i = 1; i < grid[0].size(); ++i) + { + grid[0][i] += grid[0][i - 1]; + // cout << grid[0][i] << " "; + } + + for (int i = 1; i < grid.size(); ++i) + { + grid[i][0] += grid[i - 1][0]; + cout << grid[i][0] << endl; + } + + // 计算有左边和上边的网格 + for (int i = 1; i < grid.size(); ++i) + { + for (int j = 1; j < grid[0].size(); ++j) + { + grid[i][j] += min(grid[i - 1][j], grid[i][j - 1]); + cout << grid[i][j] << " "; + } + cout << endl; + } + + return *grid.rbegin()->rbegin(); +} + + +int main() { + + vector> v = {{1,2,3},{4,5,6}}; + cout << minPathSum(v) << endl; + + return 0; +} diff --git "a/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/91.cpp" "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/91.cpp" new file mode 100644 index 0000000..483b089 --- /dev/null +++ "b/03.code/08.leetcode/03.7.8\345\210\267\351\242\230/91.cpp" @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +int numDecodings(string s) +{ + int n = s.size(); + vector f(n + 1); + f[0] = 1; + for (int i = 1; i <= n; ++i) + { + if (s[i - 1] != '0') + { + f[i] += f[i - 1]; + } + if (i > 1 && s[i - 2] != '0' && ((s[i - 2] - '0') * 10 + (s[i - 1] - '0') <= 26)) + { + f[i] += f[i - 2]; + } + } + return f[n]; +} + +int main() { + numDecodings(4); + + return 0; +}